【win32】標記選單與對話方塊背景色
阿新 • • 發佈:2019-01-01
主要是想如下的一個程式,設定了一個標記選單,在選定不同選單的時候,客戶區的顏色會改變,以此說明win32對話方塊客戶區的背景顏色設定與標記選單使用。
比起MFC裡面的背景顏色改變,WIN32的要複雜得多,而選單的修改更是需要廢一番功夫,但是通過這個程式揭示了窗體程式的本質。
一、選單設定與修改
1、如下圖,開啟Resource.h,在#ifndef之前,已有的選單項之後,為自己新設定的選單選項,設定編號。
這裡,501-503分別對應紅色、綠色、藍色三個選單:
2、之後,如下圖,對資原始檔XX.rc檢視程式碼。刪去用快捷鍵、對話方塊的程式碼。因為VS2010自帶的對話方塊,按ALT+/ ?會自動彈出對話方塊的。//自己新建的選單項 #define IDM_RED 501 #define IDM_GREEN 502 #define IDM_BLUE 503
對原有關於檔案、幫助的選單修改如下:
3、接下來,就真的可以回到Menu_Note.cpp的訊息回撥函式LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)中程式設計了。修改如下:IDC_MENU_NOTE MENU BEGIN POPUP "背景顏色改變(&C)" BEGIN MENUITEM "紅色(&R)", IDM_RED MENUITEM "綠色(&G)", IDM_GREEN MENUITEM "藍色(&B)", IDM_BLUE END END
其實,對於選單的核心在於呼叫CheckMenuRadioItem函式,第一個引數是要在其子項中設定的單選的選單的控制代碼,第二個引數和第三個引數指定合併為一個組的ID範圍,在這個範圍內的選單項被看人為同一組,這一組中,每一次只能有一項被checked,第四個引數就指定在這組項中哪一個被選中,最後一個引數決定是用ID來標識還用從0開始的索引。int menu_id=0; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; // 獲取視窗上的整個選單欄的控制代碼 auto hmm = GetMenu(hWnd); // 獲取第一個彈出選單,即[背景顏色改變]選單的控制代碼 auto hfmn = GetSubMenu(hmm, 0); HBRUSH brush;//畫刷,用於改變客戶區的背景色 RECT rect;//矩形,用於捕捉客戶區的大小 switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId)//分析視窗的選擇 { case IDM_RED: menu_id=IDM_RED; CheckMenuRadioItem(hfmn, IDM_RED, IDM_BLUE, IDM_RED, MF_BYCOMMAND);//令此選單單選 //第一個引數是選單控制代碼、第二、三個引數是指明這個選單從哪個編號到哪個編號是單選的,第四個引數是選擇誰 hdc=GetDC(hWnd); brush=CreateSolidBrush(RGB(255,0,0));//建立一個紅色畫刷 GetClientRect(hWnd,&rect);//獲取客戶區這個大矩形到rect中 FillRect(hdc,&rect,brush);//填充這個矩形 break; case IDM_GREEN: menu_id=IDM_GREEN; CheckMenuRadioItem(hfmn, IDM_RED, IDM_BLUE, IDM_GREEN, MF_BYCOMMAND); hdc=GetDC(hWnd); brush=CreateSolidBrush(RGB(0,255,0)); GetClientRect(hWnd, &rect); FillRect(hdc,&rect, brush); break; case IDM_BLUE: menu_id=IDM_BLUE; CheckMenuRadioItem(hfmn, IDM_RED, IDM_BLUE, IDM_BLUE, MF_BYCOMMAND); hdc=GetDC(hWnd); brush=CreateSolidBrush(RGB(0,0,255)); GetClientRect(hWnd, &rect); FillRect(hdc,&rect, brush); break; } break; case WM_PAINT://如果使用者移動視窗、調整視窗的大小會發生重繪,那又要重新上色 hdc = BeginPaint(hWnd, &ps); switch(menu_id){ case 0: brush=CreateSolidBrush(RGB(255,255,255)); GetClientRect(hWnd, &rect); FillRect(hdc,&rect, brush); break; case IDM_RED: brush=CreateSolidBrush(RGB(255,0,0)); GetClientRect(hWnd, &rect); FillRect(hdc,&rect, brush); break; case IDM_GREEN: brush=CreateSolidBrush(RGB(0,255,0)); GetClientRect(hWnd, &rect); FillRect(hdc,&rect, brush); break; case IDM_BLUE: brush=CreateSolidBrush(RGB(0,0,255)); GetClientRect(hWnd, &rect); FillRect(hdc,&rect, brush); break; } EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
至於設定對話方塊客戶區的背景色,這裡需要先設定畫刷的顏色,再獲取客戶區的矩形,再進行填充,填充的時候,注意獲取並初始化上下文HDC,HDC與HWND這個概念在《【win32】滑鼠響應事件》(點選開啟連結)已經提到過不在贅述。
這個程式同時需要設定一個全域性變數,記錄使用者當前選擇的是哪個標識選單,用於發生視窗重繪的時候,給客戶區的矩形重新上色。