I. Sự khác nhau giữa hộp thoại trạng thái và hộp thoại không trạng thái

Một phần của tài liệu NGÔN NGỮ LẬP TRÌNH WINDOWS (Trang 46 - 53)

s ử dụng hàm DialogBox đ ể gọi hộp thoại trạng thái và chỉ nhận được kết quả trả về khi hộp thoại này bị đóng cùng với hàm DialogBox kết thúc. Giá trị trả về của hàm này do đối sô thứ hai của hàm kết thúc hộp thoại (EndDialog) quy định. Còn đối với hộp thoại không trạng thái thì được tạo ra bằng hàm.

h D lg M o d eless= C re ateD ia lo g (h In stan ce , szT em plate, hw ndP arent, D ialogProc);

Nhưng hàm này trả quyền điều khiển v ề cho nơi gọi ngay lập tức và giá trị ưà v ề là handle của của hộp thoại hiện hành. Vì có thể có nhiều cửa sổ thao tác cùng một lúc nên bạn 1ƯC handle này đ ể d ễ dàng truy cập khi bạn cắn.

Phải đặt chế độ WS_VISIBLE cho hộp thoại không ưạng thái, bằng cách chọn mục More Styles trong cửa sổ Properties của hộp thoại. Nêu như không bật chê độ VISIBLE lên thì chương trình phải câu lệnh ShowWindow sau lời gọi hàm CreateDialog khi muốn hiển thị hộp thoại dạng này lên màn hình.

hDlgModeless=CreateDialog(hInstance, szTemplate, hwndParent, DialogProc);

S how W iiH low (liD lgM odeless,SW _SH O W );

Các thông điệp gởi đến hộp thoại dạng modal do trình quản lý Windows điều khiển cũng khác với các thông điệp gởi đến hộp thoại dạng modeless phải đi qua hằng đợi của chương trình chính. Bởi vì các thông điệp của hộp thoại dạng modeless dùng chung với các thông điệp của cửa sổ chương trình chính. Như vậy chứng ta phải lọc ra thông điệp nào là thông điệp gởi đến hộp thoại khi thao tác trên hộp thoại từ trong vòng lặp nhận thông điệp.

WINDOWS

Đ ể làm được điều này chúng ta dùng handle của hộp thoại (lưa ưong biến toàn cục) được trả vể từ lời gọi hàm CreateDialog và chuyển hướng chúng bằng đoạn lệnh như sau.

while(GetMessage(&msg, NULL, 0, 0)) {

if (hDlgModeless==0 II IIsDialogMessage (hDlgModeless, &msg);

{

TranslateMessage(&msg);

DispatchMessage(&msg);

} }

Nêu thông điệp lấy ra từ hằng đợi dành cho hộp thoại thì hàm IsDialogMessage kiểm tra và gởi đến các thủ tực xử lý hộp thoại. Và lúc này hàm ư ả v ề giá trị TRUE, còn ngược lại thì hàm ữả v ề giá trị FALSE. Nêu dùng thêm chức năng phím tăng tốc thì đoạn chương ữình trên được viết lại như sau.

whUe(GetMessage(&msg, NULL, 0, 0)) {

if (hDlgModeless==0 II !IsDialogMessage(hDlgModeless, &msg);

{

if(TranslateAccelerator (hwnd, hAccel, Stmsg) {

TranslateMessage(&msg);

DispatchMessage(&msg);

>

}

>

Nên chú ý rằng biến hDlgModeless luôn mang giá trị 0 cho đến lúc có một hộp thoại được khởi tạo bằng câu lệnh CreateDialog thì giá trị của nó mới được thay đổi. Khi cửa sổ hộp thoại bị hủy nhớ đặt hDlgModeless v ề giá trị 0. Điều này giúp Windows không gởi nhầm thông điệp xử lý đến các cửa sổ khác. Đ ể kết thúc và đóng hộp thoại dạng Modeless bạn dùng hàm DestroyWindow chứ không phải dùng hàm EndDialog như hộp thoại dạng Modal.

WINDOWS

2.22.2. Ví dụ v ề hộp thoại không không trạng thái

Đ ể minh họa cách dùng hộp thoại không trạng thái (modeless) ta xét ví dụ 2.3. Chương trình ví dụ 2.3 sau khi chạy có kết quả như sau.

Hình 2.6 Minh họa hộp thoại không trạng thái

Khi dùng chuột để chọn loại hình v ẽ trên radio button, loại hình vẽ được chọn sẽ vẽ cùng lúc lên control ünh của hộp thoại và cửa sổ chính. Dùng chuột đ ể chọn màu tô cho hình vẽ được chọn, bằng cách rê chuột lên 3 thanh cuộn Scrollbar.

Chương trình minh họa (Ví dụ 2.3) :

*OMODELESS.CPP (trích dẫn)

void PaintWindow (HWND hwnd, int iColorQ, int iFigure) {

HBRUSH hBrush ; HDC hdc ; RECT rect ;

hdc = GetDC(hwnd) ; GetClientRect (hwnd, &rect) ;

hBrush = CreateSolidBrush(RGB(iColor[0], iColor[l], iColor[2]));

hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; if (iFigure == IDC_RECT)

Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;

WINDOWS

else

Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);

DeleteObject (SelectObject (hdc, hBrush));

ReleaseDC (hwnd, hdc);

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM IParam)

{

switch (message) {

case WM_PAINT:

PaintTheBlock(hwnd, iColor, iFigure);

return 0 ;

case WM_DESTROY:

DeleteObject((HGDIOBJ)SetClassLong(hwnd, GCL_HBRBACKGROUND,(LONG)GetStockObject (WHITE JBRUSH)));

PostQuiiMessage (0);

return 0 ; }

return DefWindowProc (hwnd, message, wParam, IParam);

}

void PaintTheBlock (HWND hCtt], int iColor[], int iFigure) {

InvalidateRect (hCơl, NULL, TRUE);

UpdateWindow (hCừl);

PaintWindow (hCữl, iColor, iFigure);

}

WINDOWS

BOOL CALLBACK ColorScrDlg (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

HWND hwndParent, hC trl;

static HWND hCưlBlock;

int iCừlID, ilndex;

switch (message) {

case WM_INli DIALOG:

hCừlBlock = GetDlgltem (hDlg, IDC_PAINT);

for (iCừlID = 10; iCtrllD < 13 ; iCtrlID++) {

hCtrl = GetDlgltem (hDlg, iCtrllD);

PaintTheBlock (hCữlBlock, iColor, ¡Figure);

PaintTheBlock (hwndParent, ¡Color, iFigure);

SetScrolIRange (hCtrl, SB_CTL, 0,255, FALSE);

SetScrollPos(hQrl, SB_CTL, 0, FALSE);

}

return TRUE;

case WM_COMMAND:

{

switch( LOWORD(wParam)) {

case IDC_RECT:

case IDC_ELLIPSE:

iFigure = LOWORD(wParam);

hwndParent = GetParent (hDlg);

WINDOWS

CheckRadioButton(hDlg, IDCJRECT, IDC_ELLIPSE, LOWORD (wParam)) ; PaintTheBlock(hCtrlBlock, iColor, iFigure);

PaintTheBlock (hwndParent, iColor, iFigure);

return TRUE;

}

break;

>

case WM_VSCROLL : hCtrl = (HWND) IParam ;

iCữlID = GetWindowLong (hCtrl, GWL_ID);

ilndex = ¡Ctrl ID - 1 0 ;

hwndParent = GetParent (hDlg);

PaintTheBlock (hCttlBlock, iColor, iFigure);

PaintTheBlock (hwndParent, iColor, ¡Figure);

switch (LOWORD (wParam)) {

case SB_PAGEDOWN:

iColorfilndexJ += 1 5 ; case SBJLINEDOWN:

iColor[iIndex] = min (255, iColor[iIndex] + 1 );

break;

case SBJPAGEUP:

iColor[iIndex] -= 1 5 ; case SBJLINEUP :

iColor[iIndex] = max (0, iColor[iIndex] - 1);

break;

WINDOWS

case SB_TOP:

iColor[iIndex] = 0 ; break;

case SB_BOTTOM : iColorfilndex] = 255;

break;

case SBJTHUMBPOSITION:

case SB_THUMBTRACK:

iColor[iIndex] = HIWORD (wParam);

break;

default:

return FALSE;

>

SetScrollPos(hCtrl, SB_CTL, iColor[iIndex], TRUE);

SetDlgltemlnt (hDlg, ¡CtrlID + 3, iColor[iIndex], FALSE);

InvalidateRect(hwndParent,NULL,TRUE);

DeleteObject ( (HGDIOBJ)SetClassLong( hwndParent, GCL_HBRBACKGROUND, (LONG) CreateSoIidBrush( RGB(iColor[0], iColor[l], iColor[2])) ) ) ;

return TRUE;

case WM_PAINT:

PaintTheBlock(hCtrlBlock, iColor, iFigure);

break;

>

return FALSE;

}

WINDOWS

Một phần của tài liệu NGÔN NGỮ LẬP TRÌNH WINDOWS (Trang 46 - 53)

Tải bản đầy đủ (PDF)

(204 trang)