win32創建控件的一些問題
在我們使用CreateWindow();像一般控件建Windows擴展控件的時候我們會發現控件沒有創建成功
這是因為我們沒有對Windows擴展控件庫進行初始化,這要我們使用InitCommonControlsEx();函數來對
Windows擴展控件庫進行初始化,代碼如下:
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrls.dwICC = ICC_PAGESCROLLER_CLASS; //這里填上你要用的擴展控件類
InitCommonControlsEx(&InitCtrls);
這樣我們就可以成功創建擴展控件了。
另外對于需要調用擴展控件.dll的(MSDN里面有說明)
我們需要 HINSTANCE hInstRich = ::LoadLibrary(_T("Riched32.dll")); 加載DLL到實例句柄
hWndEditU = CreateWindowEx(NULL,L"RichEdit",L"顯示",WS_CHILD|WS_VISIBLE|WS_BORDER|
ES_LEFT|ES_MULTILINE ,10,10,400,320,hWnd,NULL,hInstRich,NULL);
這樣創建之后我們就可以調用出 擴展控件來進行編寫了!
需要注意的是在我們使用完之后需要釋放DLL的
::FreeLibrary(hInstRich);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
問題描述:
采用Win32 SDK編程,主窗口顯示采用DialogBox()函數,在窗口中添加了List control控件后,程序一運行就退出,刪除List control控件后,程序就可以正常運行了。
解決過程:
調試發現,對話框中添加了list control后,DialogBox返回值為-1,然而GetLastError()返回值為0,在對話框的回調函數中的消息處理上添加斷點,發現調用DialogBox()后已經進入消息循環。把List control刪除后,程序也就能正常運行了,這是為何?唉,苦惱中……
解決辦法:
在DialogBox()函數前添加InitCommonControls(); 同時別忘了添加#include <commctrl.h>哦!
知識擴展:
因為公共控件同操作系統核心是分離的,所以在使用任何一個公共控件前必須要初始化包含公共控件的DLL。在所有Windows版本里,也包括Windows CE,您可以調用void InitCommonControls(void)來裝載動態庫并注冊許多公共控件類。該調用并不初始化日歷控件、時間選擇控件、up/down控件、IP地址控件以及其它更新一些的公共控件。要初始化這些控件,使用函數BOOL InitCommonControlsEx(LPINITCOMMONCONTROLSEX lpInitCtrls); 該函數允許應用程序只裝載和初始化選擇的公共控件。該函數在Windows CE下很容易獲得,因為只裝載需要的控件可以減少對內存的影響。該函數唯一的參數是一個含有兩個域的結構,該結構有一個尺寸域和一個包含標志集的域,標志集用來指出哪些公共控件需要被注冊。下表給出了可以使用的標志及對應的控件。
公共控件對應的標志
Flag
Control Classes Initialized
一旦公共控件DLL被初始化,這些公共控件就可以像其它任何控件一樣對待了。每個控件都有一個可定制風格標志集,用來配置控件的外觀和行為。針對每個控件的消息會被發出,用來配置和操縱控件并讓控件執行某些動作。標準Windows控件和公共控件之間的一個主要差別是事件通知或服務請求是通過WM_NOTIFY消息來發出,而標準控件則是通過WM_COMMAND消息發出的。同通過WM_COMMAND消息發出的通知相比,采用這種技術可以使通知能夠包含更多的信息。另外,這種技術允許為每個使用該通知的控件進行擴展和改編WM_NOTIFY消息。
WM_NOTIFY消息在lParam參數中攜帶著指向NMHDR結構的指針,NMHDR定義如下:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
hwndFrom是發送通知消息的窗口句柄。對屬性頁來說,就是屬性頁窗口。如果是控件發送通知的話,idFrom就是控件ID。最后一個code域包含的是通知碼。同WM_COMMAND消息相比,雖然這個基本結構沒有包含任何更多的信息,但它幾乎總是可以擴展的,可以使用附加域來擴展它。通知碼指出有什么樣的附加域附加到了該通知結構里。
公共控件編程中另一個不同點是發給公共控件的大部分與控件相關的消息都有預定義的宏,用這些宏來發送消息,看上去像是應用程序在調用函數。所以不用像下面的語句那樣使用LVM_INSERTITEM消息來給列表控件插入一個項,如
nIndex = (int) SendMessage (hwndLV, LVM_INSERTITEM, 0, (LPARAM)&lvi);
而是可以很容易地使用nIndex = ListView_InsertItem (hwndLV, &lvi)即可。
這兩行語句沒有功能上的差別。用宏地優勢是清晰。宏和其它公共控件編程中需要的定義們一起都位于CommCtrl.h中。用這些宏的一個問題是編譯器不能對參數執行類型檢查,而假如宏是真正的函數的話是本應該執行的。這個問題也存在于SendMessage技術中,在SendMessage這種方式中參數必須是WPARAM和LPARAM類型,但消息缺乏類型檢查也是比較常見的。總的來說,宏例程還是提供了更好的可讀性。宏系統的一個例外是在命令條控件和命令帶控件中進行宏調用的時候。在這些控件中,除了有大量的用宏包裝的消息外,實際上還有許多真的函數。通常,我所說的消息是真正的消息,而不是它們對應的宏。這將有助于將消息或者宏同真正的函數區分開來。
參考文獻:
<<Programming Microsoft Windows CE .NET, Third Edition>> byDouglas Boling
=================================================================================
win32 下為edit編輯框增加新的一行內容
::SendMessage(hWnd, EM_SETSEL, -1, -1);
::SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)lpszText);