Dialog

Cửa sổ Dialog hoặc các dialog là phần quan trọng của GUI. Dialog được sử dụng để lấy dữ liệu, chỉnh sửa dữ liệu, thay đổi cài đặt ứng dụng,..

Dialog Box

#include "windows.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);

void CreateDialogBox(HWND);
void RegisterDialogClass(HWND);

HINSTANCE ghInstance;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    MSG msg;
    HWND hwnd;
    WNDCLASS wc = {0};
    wc.lpszClassName = TEXT( "Window" );
    wc.hInstance = hInstance ;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc = WndProc;
    RegisterClass(&wc);
    hwnd = CreateWindow( wc.lpszClassName, TEXT("Window"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 250, 150, NULL, NULL, hInstance, NULL);

    ghInstance = hInstance;
    while( GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
    }
    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch(msg)
    {
    case WM_CREATE:
        RegisterDialogClass(hwnd);
        CreateWindow(TEXT("button"), TEXT("Show dialog"), WS_VISIBLE | WS_CHILD , 20, 50, 95, 25, hwnd, (HMENU) 1, NULL, NULL);
        break;
     case WM_COMMAND:
        CreateDialogBox(hwnd);
        break;
     case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

LRESULT CALLBACK DialogProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch(msg)
    {
    case WM_CREATE:
        CreateWindow(TEXT("button"), TEXT("Ok"), WS_VISIBLE | WS_CHILD , 50, 50, 80, 25, hwnd, (HMENU) 1, NULL, NULL);
        break;
    case WM_COMMAND:
        DestroyWindow(hwnd);
        break;
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    }
    return (DefWindowProc(hwnd, msg, wParam, lParam));
}

void RegisterDialogClass(HWND hwnd)
{
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpfnWndProc = (WNDPROC) DialogProc;
    wc.hInstance = ghInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpszClassName = TEXT("DialogClass");
    RegisterClassEx(&wc);
}

void CreateDialogBox(HWND hwnd)
{
    CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_TOPMOST, TEXT("DialogClass"), TEXT("Dialog Box"), WS_VISIBLE | WS_SYSMENU | WS_CAPTION , 100, 100, 200, 150, NULL, NULL, ghInstance, NULL);
}

Giải thích:
Trong ví dụ trên, chúng ta khai báo 2 hàm xử lí message.

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);

– Hàm thứ nhất, xử lí các message phát sinh tại cửa sổ “Window” được tạo ban đầu ngay khi chạy ứng dụng.
– Khi ta click vào button “Show dialog” chương trình sẽ tạo ra cửa sổ thứ hai. Nếu người sử dụng thao tác trên cửa sổ “Dialog Box” thì hàm xử lí message thứ hai sẽ được gọi.

Kết quả:

Dialog Box

Colour Dialog Box

#include "windows.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK PanelProc(HWND, UINT, WPARAM, LPARAM);

void RegisterPanel(void);
COLORREF ShowColorDialog(HWND);

COLORREF gColor = RGB(255, 255, 255);

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow )
{
    MSG msg;
    WNDCLASS wc = {0};
    wc.lpszClassName = TEXT( "Color dialog box" );
    wc.hInstance= hInstance ;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc = WndProc ;
    RegisterClass(&wc);
    CreateWindow( wc.lpszClassName, TEXT("Color dialog box"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 150, 150, 250, 200, 0, 0, hInstance, 0);

    while( GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
    }
    return (int) msg.wParam;
}


LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    static HWND hwndPanel;
    switch(msg)
    {
    case WM_CREATE:
    {
        CreateWindow(TEXT("button"), TEXT("Color"), WS_VISIBLE | WS_CHILD, 20, 30, 80, 25, hwnd, (HMENU) 1, NULL, NULL);
        RegisterPanel();
        hwndPanel = CreateWindow(TEXT("Panel"), NULL, WS_CHILD | WS_VISIBLE, 130, 30, 80, 80, hwnd, (HMENU) 2, NULL, NULL);
        break;
    }
    case WM_COMMAND:
    {
        gColor = ShowColorDialog(hwnd);
        InvalidateRect(hwndPanel, NULL, TRUE);
        break;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

LRESULT CALLBACK PanelProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;

    switch(msg)
    {
    case WM_PAINT:
    {
        GetClientRect(hwnd, &rect);
        hdc = BeginPaint(hwnd, &ps);
        SetBkColor(hdc, gColor);
        ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, TEXT(""), 0, NULL);
        EndPaint(hwnd, &ps);
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

COLORREF ShowColorDialog(HWND hwnd) 
{
    CHOOSECOLOR cc;
    static COLORREF crCustClr[16];
    ZeroMemory(&cc, sizeof(cc));
    cc.lStructSize = sizeof(cc);
    cc.hwndOwner = hwnd;
    cc.lpCustColors = (LPDWORD) crCustClr;
    cc.rgbResult = RGB(0, 255, 0);
    cc.Flags = CC_FULLOPEN | CC_RGBINIT;
    ChooseColor(&cc);

    return cc.rgbResult;
}

void RegisterPanel(void) 
{
    WNDCLASS rwc = {0};
    rwc.lpszClassName = TEXT( "Panel" );
    rwc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    rwc.lpfnWndProc = PanelProc;
    RegisterClass(&rwc);
}

Giải thích:
Trong ví dụ này, chúng ta có 1 button và 1 child window. Màu của child window được khởi tạo là màu trắng. Chúng ta có thể thay đổi màu của child window bằng cách click vào button “Colour” và chọn màu tùy ý.

COLORREF gColor = RGB(255, 255, 255);

Sử dụng macro RGB(255, 255, 255) để khởi tạo màu cho child window.

gColor = ShowColorDialog(hwnd);

Hàm này trả về giá trị màu được chọn.

CHOOSECOLOR cc;

Để tạo Color Dialog Box ta cần định nghĩa cấu trúc CHOOSECOLOR.

cc.rgbResult = RGB(0, 255, 0);
cc.Flags = CC_FULLOPEN | CC_RGBINIT;

Khởi tạo màu trên Dialog Box.

ChooseColor(&cc);

Sau khi người dùng chọn màu trên Dialog Box và nhấn OK. Hàm ChooseColor(&cc) sẽ trả về giá trị khác không và đồng thời giá trị màu được chọn được gán cho thông số rgbResult.

Hàm ShowColorDialog(HWND hwnd) sẽ trả về giá trị màu đã được chọn.

return cc.rgbResult;
InvalidateRect (hwndPanel, NULL, TRUE);

Sau khi lấy được màu đã chọn. Chúng ta gọi hàm InvalidateRect(), hàm này sẽ gửi tới child window message WM_PAINT.

SetBkColor(hdc, gColor);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, TEXT(""), 0, NULL);

Hàm SetBkColor() cài đặt màu của background. Hàm ExtTextOut() có chức năng hiển thị văn bản và màu lên device context. Ở đây ETO_OPAQUE là hằng số đã được định nghĩa, khi giá trị này được khai báo thì hàm ExtTextOut() chỉ hiển thị màu lên background.

Kết quả:

Color Dialog

Be the first to comment

Leave a Reply