一,窗体创建
二,窗体类
三,窗体显示
四,应用程序消息循环
一,窗体创建
HWND CreateWindow(
LPCTSTR lpClassName, // registered class name
LPCTSTR lpWindowName, // window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window//父窗体或者拥有者窗体,注意,在这里请想一下为什么自始至终没有使用DestroyWindow呢?
HMENU hMenu, // menu handle or child identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // window-creation data //当WM_CREATE将CREATESTRUCT 传给它.
);
HWND CreateWindowEx(
DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // registered class name
LPCTSTR lpWindowName, // window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window//父窗体或者拥有者窗体,注意,在这里请想一下为什么自始至终没有使用DestroyWindow呢?
HMENU hMenu, // menu handle or child identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // window-creation data //当WM_CREATE将CREATESTRUCT 传给它.
);
创建一个overlapped, pop-up, or child窗体,注意这里sytle,为什么要强调sytle呢?因为他决定的接受或拒绝的消息,而windows是消息循环驱动,消息是他的心脏。
二,窗体类
typedef struct _WNDCLASS {
UINT style;
WNDPROC lpfnWndProc; //消息循环
int cbClsExtra; //0类扩展
int cbWndExtra; //0窗体扩展
HINSTANCE hInstance; //模块句柄
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName; //注意这里又一个菜单名称,CreateWindow里的是HMENU,含义不同
LPCTSTR lpszClassName;
} WNDCLASS, *PWNDCLASS;
typedef struct _WNDCLASSEX {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm; //小图标
} WNDCLASSEX, *PWNDCLASSEX;
ATOM RegisterClass(
CONST WNDCLASS *lpWndClass // class data
);
ATOM RegisterClassEx(
CONST WNDCLASSEX *lpwcx // class data
);
第二包括版本控制(cbSize),以及加入了一个小图标(hIconSm)资源.
三,窗体显示
BOOL ShowWindow(
HWND hWnd, // handle to window
int nCmdShow // show state
);
在Form的CM_SHOWINGCHANGED也是用的这个方法,也就是设置visible后.当然普通子控件并不是如此(SetWindowPos).
BOOL UpdateWindow(
HWND hWnd // handle to window
);
直接发送一个只有刷新区域的wm_paint消息给hWnd,所以此函数意义不大.
四,应用程序消息循环
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); //Windows消息分派函数,消息循环的精髓
}
BOOL GetMessage(
LPMSG lpMsg, // message information
HWND hWnd, // handle to window,特定的窗体句柄,这个地方容易和具体窗体消息处理过程搞混.
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax // last message
);
主要看这个函数的返回值:只有收到的是WM_QUIT才返回0,也就是FALSE,退出消息循环(所以可以直接发送WM_QUIT退出系统).
Windows.PostMessage(Handle,wm_quit,0,0);注意第一必须用PostMessage(上次说过sendmessage消息队列不同),第二句柄可以是当前线程任何窗体.
Delphi消息循环:
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then //特别注意这里的键盘消息,提示框消息以及对话消息处理
begin
TranslateMessage(Msg);
DispatchMessage(Msg); //这是个神奇的函数
end;
end
else
FTerminate := True; //结束消息循环
end;a
procedure TApplication.Run;
....
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
.....
end;
until Terminated;
以上四个知识点,我相信大部分人都有接触过,但真正意义上地想清楚的人不多,希望和大家一起把这四个知识点想清楚.
就我自己而言,接触了无数遍,时间不下于五年,以上例子就是从06年的<<Windows程序设计>>,至今未得真解.
今天到此,后面还有很多window控件,button,static,edit,combobox,listview,scrollbar,richedit,让我们一步一步揭开windows的神秘面纱.
----------20100630 Henry