子視窗控制元件(轉)
本課中我們將探討控制元件,這些控制元件是我們程式主要的輸入輸出裝置。
理論:
WINDOWS 提供了幾個預定義的視窗類以方便我們的使用。大多數時間內,我們把它們用在對話方塊中,所以我們一般就它們叫做子視窗控制元件。子視窗控制元件會自己處理訊息,並在自己狀態發生改變時通知父視窗。這樣就大大地減輕了我們的程式設計工作,所以我們應儘可能地利用它們。本課中我們把這些控制元件放在視窗中以簡化程式,但是大多數時間內子視窗控制元件都是放在對話方塊中的。我們示例中演示的子視窗控制元件包括:按鈕、下拉選單、檢查框、單選按鈕、編輯框等。使用子視窗控制元件時,先呼叫CreateWindow 或 CreateWindowEx。在這裡由於WINDOWS 已經註冊了這些子控制元件,所以無須我們再註冊。當然我們不能改變它們的類名稱。譬如:如果您想產生一個按鈕,在呼叫上述兩個函式時就必須指定類名為"button"。其他必須指定的引數還有父視窗的控制程式碼和將要產生的子控制元件的ID號。子控制元件的ID號是用來標識子控制元件的,故也必須是唯一 的。子控制元件產生後,當其狀態改變時將會向父視窗傳送訊息。一般我們應在父視窗的WM_CREATE訊息中產生字控制元件。子控制元件向父視窗傳送的訊息是WM_COMMAND,並在傳遞的引數wPara的底位中包括控制元件的ID號,訊息號在wParam的高位,lParam中則包括了子控制元件的視窗的控制程式碼。各類控制元件有不同的訊息程式碼集,詳情請參見WIN32 API參考手冊。父視窗也可以透過呼叫函式SendMessage向子控制元件傳送訊息,其中第一個引數是子控制元件的視窗控制程式碼,第二個引數是要傳送的訊息號,附加的引數可以在wParam和lParam中傳遞,其實只要知道了某個視窗的控制程式碼就可以用該函式向其傳送相關訊息。所以產生了子視窗後必須處理WM_COMMAND訊息以便可以接收到子控制元件的訊息。
例子:
我們將產生一個視窗,在該視窗中有一個編輯框和一個按鈕。當您按下按鈕時 ,會彈出一個對話方塊其中顯示了您在編輯框中輸入的內容。另外,該應用程式還有一個選單,其中有四個選單項:
Say Hello -- 把一個字串輸入編輯控制元件;
Clear Edit Box -- 清除編輯控制元件中的字串;
Get Text -- 彈出對話方塊顯示編輯控制元件中的字串;
Exit -- 退出應用程式。
.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include masm32includewindows.inc
include masm32includeuser32.inc
include masm32includekernel32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
MenuName db "FirstMenu",0
ButtonClassName db "button",0
ButtonText db "My First Button",0
EditClassName db "edit",0
TestString db "Wow! I'm in an edit box now",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndButton HWND ?
hwndEdit HWND ?
buffer db 512 dup(?) ; buffer to store the text retrieved from the edit box
.const
ButtonID equ 1 ; The control ID of the button control
EditID equ 2 ; The control ID of the edit control
IDM_HELLO equ 1
IDM_CLEAR equ 2
IDM_GETTEXT equ 3
IDM_EXIT equ 4
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,OFFSET MenuName
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,
ADDR AppName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
300,200,NULL,NULL, hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,WS_EX_CLIENTEDGE, ADDR EditClassName,NULL,
WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or
ES_AUTOHSCROLL,
50,35,200,25,hWnd,8,hInstance,NULL
mov hwndEdit,eax
invoke SetFocus, hwndEdit
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,
75,70,140,25,hWnd,ButtonID,hInstance,NULL
mov hwndButton,eax
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF lParam==0
.IF ax==IDM_HELLO
invoke SetWindowText,hwndEdit,ADDR TestString
.ELSEIF ax==IDM_CLEAR
invoke SetWindowText,hwndEdit,NULL
.ELSEIF ax==IDM_GETTEXT
invoke GetWindowText,hwndEdit,ADDR buffer,512
invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK
.ELSE
invoke DestroyWindow,hWnd
.ENDIF
.ELSE
.IF ax==ButtonID
shr eax,16
.IF ax==BN_CLICKED
invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0
.ENDIF
.ENDIF
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
分析:
我們現在開始分析,
.ELSEIF uMsg==WM_CREATE
invoke CreateWindowEx,WS_EX_CLIENTEDGE,
ADDR EditClassName,NULL,
WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT
or ES_AUTOHSCROLL,
50,35,200,25,hWnd,EditID,hInstance,NULL
mov hwndEdit,eax
invoke SetFocus, hwndEdit
invoke CreateWindowEx,NULL, ADDR ButtonClassName,
ADDR ButtonText,
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,
75,70,140,25,hWnd,ButtonID,hInstance,NULL
mov hwndButton,eax
我們在WM_CREATE中產生子控制元件,其中在函式CreateWindowEx中給子控制元件視窗一個WS_EX_CLIENTEDGE風格,它使得子控制元件視窗看上去邊界下凹,具有立體感。每一個子控制元件的類名都是預定義的,譬如:按鈕的預定義類名是"button",編輯框是"edit"。接下來的引數是視窗風格,除了通常的視窗風格外,每一個控制元件都有自己的擴充套件風格,譬如:按鈕類的擴充套件風格前面加有BS_,編輯框類則是:ES_,WIN32 API 參考中有所有的擴充套件風格的描述。注意:您在CreateWindowsEx函式中本來要傳遞選單控制程式碼的地方傳入子視窗空間的ID號不會有什麼副作用,因為子視窗控制元件本身不能有選單。產生控制元件後,我們儲存它們的控制程式碼,然後呼叫SetFocus把焦點設到編輯控制元件上以便使用者立即可以輸入。接下來的是如何處理控制元件傳送的通知訊息WM_COMMAND:
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.IF lParam==0
我們以前講過選擇選單想也會傳送WM_COMMAND 訊息,那我們應如何區分呢?看了下表您就會一目瞭然:
Low word of wParam High word of wParam lParam
Menu Menu ID 0 0
Control Control ID Notification code Child Window Handle
其中我們可以看到不能用wParam來區分,因為選單和控制元件的ID號可能相同,而且子視窗空間的訊息號也有可能為0。
.IF ax==IDM_HELLO
invoke SetWindowText,hwndEdit,ADDR TestString
.ELSEIF ax==IDM_CLEAR
invoke SetWindowText,hwndEdit,NULL
.ELSEIF ax==IDM_GETTEXT
invoke GetWindowText,hwndEdit,ADDR buffer,512
invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK
您可以呼叫SetWindowText函式把一字串繁縟到編輯控制元件中去,為了清0,傳入NULL值。SetWindowText是一個通用函式,即可以用它來設定一個視窗的標題,也可以用它來改變一個按鈕上的文字。如果是要得到按鈕上的文字,則呼叫GetWindowText。
.IF ax==ButtonID
shr eax,16
.IF ax==BN_CLICKED
invoke SendMessage,hWnd,WM_COMMAND,IDM_GETTEXT,0
.ENDIF
.ENDIF
上面的片段是處理使用者按鈕事件的。他首先檢查wParam的高位元組看是否是按鈕的ID 號,若是則檢查低位元組看傳送的訊息號是否BN_CLICKED,該訊息是在按鈕按下時傳送的,如果一切都對,則轉入處理該訊息,我們可以從處理訊息IDM_GETTEXT處複製全部的程式碼,但是更專業的辦法是在傳送一條IDM_GETTEXT訊息讓主視窗過程處理,這隻要把傳送的訊息設定為WM_COMMAND,再把wParam的低位元組中設定為IDM_GETTEXT即可。這樣一來您的程式碼就簡潔了許多,所以儘可能利用該技巧。最後,當然不是或有或無,必須在訊息迴圈中呼叫函式TranslateMessage,因為您的應用程式需要在編輯框中輸入可讀的文字。如果省略了該函式,就不能在編輯框中輸入任何東西。
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10172717/viewspace-928722/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MFC操作父視窗的子控制元件控制元件
- 工作列視窗以及其子視窗結構 (轉)
- jQuery在子視窗如何操作父視窗元素jQuery
- js如何在子視窗中關閉父視窗JS
- 討論關閉子視窗,重新整理父視窗(非模式視窗)模式
- Qt入門(14)——父視窗部件和子視窗部件QT
- C#中關閉子視窗而不釋放子視窗物件的方法C#物件
- QT 讓視窗(或控制元件)居中QT控制元件
- BCB 窗體透明控制元件 (轉)控制元件
- jQuery iframe子視窗獲取父視窗元素簡單介紹jQuery
- PyQt5視窗繪圖控制元件QT繪圖控制元件
- 關於父視窗獲取跨域iframe子視窗中的元素跨域
- FineUI小技巧(5)向子視窗傳值,向父視窗傳值UI
- JavaScript視窗功能指南之操縱視窗 (轉)JavaScript
- js的開啟子視窗 shwoModalDialogJS
- PyQt5——視窗繪圖類控制元件QT繪圖控制元件
- JavaScript視窗功能指南之命名視窗和框架 (轉)JavaScript框架
- JavaScript視窗功能指南之定製新視窗 (轉)JavaScript
- JavaScript視窗功能指南之發揮視窗特徵 (轉)JavaScript特徵
- JavaScript視窗功能指南之建立彈出視窗 (轉)JavaScript
- SWT的視覺化控制元件的X11視窗控制程式碼簡介(轉)視覺化控制元件
- 一個問題——在MDI窗體中新增控制元件後顯示子窗體控制元件
- 在列印視窗,列印檢視View的子檢視結構圖View
- Linux 文件與視窗(轉)Linux
- 列表檢視控制元件(轉)控制元件
- JavaScript視窗功能指南之在視窗中書寫內容 (轉)JavaScript
- Windows常見視窗樣式和控制元件風格Windows控制元件
- JavaScript視窗功能指南之檢查一個視窗是否存在 (轉)JavaScript
- 人工設定視窗圖示 (轉)
- Javascript自動關閉視窗(轉)JavaScript
- 樹型檢視控制元件(轉)控制元件
- javascript在iframe子元素中獲取父視窗元素JavaScript
- C# winForm 視窗跳轉後關閉上一個視窗的方法C#ORM
- Delpi在MDI視窗中顯示圖形控制元件及指定背景的解決方案 (轉)控制元件
- 子控制元件控制元件
- mfc+最大最小化視窗+控制元件變化+圖片(視訊幀)顯示在控制元件上控制元件
- 使用C#開啟新視窗關閉舊視窗的方法;winform中防止重複開啟多個相同子窗體C#ORM
- C# API-拖動無標題視窗及控制元件C#API控制元件