《windows核心编程》(六)-----------2013.8.1
一、概念
窗口的创建
Window style(窗口风格)
WS_BORDER 有边框窗口
WS_CAPTION 必须和WS_BORDER风格配合,但不能与WS_DLGFRAME风格一起使用。
指示窗口包含标题要部分。
WS_CHILD 说明窗口为子窗口,不能应用于弹出式窗口风格(WS_POPUP)。
WS_CHILDWINDOW 同WS_CHILD。
WS_CLIPCHILDREN 绘制父窗口时,不绘制子窗口的裁剪区域。使用在建立父窗口时。
WS_CLIPSIBLINGS 剪裁相关的子窗口,这意味着,当一个特定的子窗口接收到重绘
消息时,WS_CLIPSIBLINGS风格将在子窗口要重画的区域中去掉与其它子窗口重叠
的部分。(如果没有指定WS_CLIPSIBLINGS风格,并且子窗口有重叠,当你在一个
子窗口的客户区绘图时,它可能会画在相邻的子窗口的客户区中。)只与WS_CHILD
风格一起使用。
WS_DISABLED 创建一个初始状态为禁止的窗口。
WS_DLGFRAME 创建一个窗口,具有双重边界,但是没有标题条。
WS_GROUP 指定一组控件中的第一个,用户可以用箭头键在这组控件中移动。在第
一个控件后面把WS_GROUP风格设置为FALSE的控件都属于这一组。下一个具有
WS_GROUP风格的控件将开始下一组(这意味着一个组在下一组的开始处结束)。
WS_HSCROLL 创建一个具有水平滚动条的窗口。
WS_ICONIC:创建一个初始状态为最小化状态的窗口。与WS_MINIMIZE风格相同。
WS_MAXIMIZE 创建一个最大化的窗口。
WS_MAXIMIZEBOX 创建一个具有最大化按钮的窗口。
WS_MINIMIZE 创建一个初始状态为最小化的窗口。仅与WS_OVERLAPPED风格一起使用。
WS_MINIMIZEBOX 创建一个具有最小化按钮的窗口。
WS_OVERLAPPED 创建一个重叠窗口。重叠窗口通常具有标题条和边界。
WS_OVERLAPPEDWINDOW 创建一个具有
WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU,WS_THICKFRAME,WS_MINIMIZEBOX和
WS_MAXIMIZEBOX风格的重叠式窗口。
WS_POPUP 创建一个弹出式窗口,不能与WS_CHILD风格一起使用。
WS_POPUPWINDOW 创建一个具有WS_BORDER,WS_POPUP和WS_SYSMENU风格的弹出窗
口。为了使控制菜单可见,必须与WS_POPUPWINDOW一起使用WS_CAPTION风格。
WS_SIZEBOX:创建一个可调边框的窗口,与WS_THICKFRAME风格相同。
WS_SYSMENU 创建一个在标题条上具有控制菜单的窗口。仅对带标题条的窗口使用。
WS_TABSTOP 指定了一些控件中的一个,用户可以通过TAB键来移过它。TAB键使用
户移动到下一个用WS_TABSTOP风格定义的控件。
WS_THICKFRAME 创建一个具有厚边框的窗口,可以通过厚边框来改变窗口大小。
WS_TILED:产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与
WS_OVERLAPPED风格相同。
WS_TILEDWINDOW:创建一个具有
WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU,MS_THICKFRAME风格的窗口。
WS_VISIBLE 创建一个最初可见的窗口。
WS_VSCROLL 创建一个具有垂直滚动条的窗口。
扩展窗口风格(Extended window style)
WS_EX_ACCEPTFILES 指明用这个风格创建的窗口能够接受拖放文件。
•CreateWindow/CreateWindowEx
•HWND CreateWindowEx(
• DWORD dwExStyle, //窗口的扩展风格
• LPCTSTR lpClassName, //已经注册的窗口类名称
• LPCTSTR lpWindowName, //窗口标题栏的名字
• DWORD dwStyle, //窗口的基本风格
• int x, //窗口左上角水平坐标位置
• int y, //窗口左上角垂直坐标位置
• int nWidth, //窗口的宽度
• int nHeight,//窗口的高度
• HWND hWndParent,//窗口的父窗口句柄
• HMENU hMenu,//窗口菜单句柄
• HINSTANCE hInstance, //应用程序实例句柄
• LPVOID lpParam //窗口创建时附加参数
•); 创建成功返回窗口句柄
Window style(窗口风格)
WS_BORDER 有边框窗口
WS_CAPTION 必须和WS_BORDER风格配合,但不能与WS_DLGFRAME风格一起使用。
指示窗口包含标题要部分。
WS_CHILD 说明窗口为子窗口,不能应用于弹出式窗口风格(WS_POPUP)。
WS_CHILDWINDOW 同WS_CHILD。
WS_CLIPCHILDREN 绘制父窗口时,不绘制子窗口的裁剪区域。使用在建立父窗口时。
WS_CLIPSIBLINGS 剪裁相关的子窗口,这意味着,当一个特定的子窗口接收到重绘
消息时,WS_CLIPSIBLINGS风格将在子窗口要重画的区域中去掉与其它子窗口重叠
的部分。(如果没有指定WS_CLIPSIBLINGS风格,并且子窗口有重叠,当你在一个
子窗口的客户区绘图时,它可能会画在相邻的子窗口的客户区中。)只与WS_CHILD
风格一起使用。
WS_DISABLED 创建一个初始状态为禁止的窗口。
WS_DLGFRAME 创建一个窗口,具有双重边界,但是没有标题条。
WS_GROUP 指定一组控件中的第一个,用户可以用箭头键在这组控件中移动。在第
一个控件后面把WS_GROUP风格设置为FALSE的控件都属于这一组。下一个具有
WS_GROUP风格的控件将开始下一组(这意味着一个组在下一组的开始处结束)。
WS_HSCROLL 创建一个具有水平滚动条的窗口。
WS_ICONIC:创建一个初始状态为最小化状态的窗口。与WS_MINIMIZE风格相同。
WS_MAXIMIZE 创建一个最大化的窗口。
WS_MAXIMIZEBOX 创建一个具有最大化按钮的窗口。
WS_MINIMIZE 创建一个初始状态为最小化的窗口。仅与WS_OVERLAPPED风格一起使用。
WS_MINIMIZEBOX 创建一个具有最小化按钮的窗口。
WS_OVERLAPPED 创建一个重叠窗口。重叠窗口通常具有标题条和边界。
WS_OVERLAPPEDWINDOW 创建一个具有
WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU,WS_THICKFRAME,WS_MINIMIZEBOX和
WS_MAXIMIZEBOX风格的重叠式窗口。
WS_POPUP 创建一个弹出式窗口,不能与WS_CHILD风格一起使用。
WS_POPUPWINDOW 创建一个具有WS_BORDER,WS_POPUP和WS_SYSMENU风格的弹出窗
口。为了使控制菜单可见,必须与WS_POPUPWINDOW一起使用WS_CAPTION风格。
WS_SIZEBOX:创建一个可调边框的窗口,与WS_THICKFRAME风格相同。
WS_SYSMENU 创建一个在标题条上具有控制菜单的窗口。仅对带标题条的窗口使用。
WS_TABSTOP 指定了一些控件中的一个,用户可以通过TAB键来移过它。TAB键使用
户移动到下一个用WS_TABSTOP风格定义的控件。
WS_THICKFRAME 创建一个具有厚边框的窗口,可以通过厚边框来改变窗口大小。
WS_TILED:产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与
WS_OVERLAPPED风格相同。
WS_TILEDWINDOW:创建一个具有
WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU,MS_THICKFRAME风格的窗口。
WS_VISIBLE 创建一个最初可见的窗口。
WS_VSCROLL 创建一个具有垂直滚动条的窗口。
扩展窗口风格(Extended window style)
WS_EX_APPWINDOW - 当窗口可见时将一个顶层窗口放置在任务栏上。
WS_EX_CLIENTEDGE 指明窗口具有3D外观,这意味着,边框具有下沉的边界。
WS_EX_CONTEXTHELP 在窗口的标题条中包含问号。当用户单击问号时,鼠标光标的
形状变为带指针的问号。如果用户随后单击一个子窗口,子窗口将接收到一个
WM_HELP消息。
WS_EX_CONTROLPARENT 允许用户用TAB键遍历窗口的子窗口。
WS_EX_DLGMODALFRAME 指明一个具有双重边界的窗口,当你在dwStyle参数中指定
了WS_CAPTION风格标志时,它可以具有标题条(可选)。
WS_EX_LEFT 指定窗口具有左对齐属性。这是缺省值。
WS_EX_LEFTSCROLLBAR 将垂直滚动条放在客户区的左边。
WS_EX_LTRREADING 按照从左到右的方式显示窗口文本。这是缺省方式。
WS_EX_MDICHILD 创建一个MDI子窗口。
WS_EX_NOPARENTNOTIFY 指定用这个风格创建的子窗口在被创建或销毁的时候将不
向父窗口发送WM_PARENTNOTIFY消息。
WS_EX_OVERLAPPEDWINDOW 组合了WS_EX_CLIENTEDGE和WS_EX_WIND-OWEDGE风格。
WS_EX_PALETTEWINDOW 组合了WS_EX_WINDOWEDGE和WS_EX_TOPMOST风格。
WS_EX_RIGHT 赋予窗口右对齐属性。这与窗口类有关。
WS_EX_RIGHTSCROLLBAR 将垂直滚动条(如果有)放在客户区的右边。这是缺省方式。
WS_EX_RTLREADING 按照从右到左的顺序显示窗口文本。
WS_EX_STATICEDGE 创建一个具有三维边界的窗口,用于不接受用户输入的项。
WS_EX_TOOLWINDOW 创建一个工具窗口,目的是被用作浮动工具条。工具窗口具有
标题条,比通常的标题条要短,窗口的标题是用小字体显示的。工具窗口不出现在
任务条或用户按下ALT+TAB时出现的窗口中。
WS_EX_TOPMOST 指定用这个风格创建的窗口必须被放在所有非顶层窗口的上面,即
使这个窗口已经不处于激活状态,它还是保留在最上面。应用程序可以用
SetWindowsPos成员函数来加入或去掉这个属性。
WS_EX_TRANSPARENT 指定了用这个风格创建的窗口是透明的。这意味着,在这个窗
口下面的任何窗口都不会被这个窗口挡住。用这个风格创建的窗口只有当它下面的
窗口都更新过以后才接收WM_PAINT消息。
WS_EX_WINDOWEDGE 指定了具有凸起边框的窗口。
子窗口的创建
子窗口创建示例:
运行结果:
为什么会出现两个C2窗口?
因为C1窗口还未更新。
修复方法,只要最小化窗口在恢复就好了。
如图:
二、问题
•创建时要设置父窗口句柄
•只要是创建子窗口就要添加WS_CHIDE | WS_VISBLE
MoveWindow() 函数
MoveWindow() 函数
BOOL MoveWindow(
HWND hWnd,//窗口句柄
int X,//水平位置
int Y,//垂直位置
int nWidth,//宽
int nHeight,//高
BOOL bRepaint//重绘标识 true:重绘 false:不重绘
);
子窗口创建示例:
// WinCreate.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "WinCreate.h"
#include "windows.h"
HINSTANCE g_hInstance = 0;
//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)
{
switch(nMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,nMsg,wParam,lParam);
}
//注册窗口类
BOOL Register(LPTSTR lpClassName,WNDPROC wndproc)
{
WNDCLASSEX wce = {0};
wce.cbSize = sizeof(wce);
wce.cbClsExtra = 0;
wce.cbWndExtra = 0;
wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wce.hCursor = NULL;
wce.hIcon = NULL;
wce.hIconSm = NULL;
wce.hInstance = g_hInstance;
wce.lpfnWndProc = wndproc;
wce.lpszClassName = lpClassName;
wce.lpszMenuName = NULL;
wce.style = CS_HREDRAW | CS_VREDRAW;
ATOM nAtom = RegisterClassEx(&wce);
if(nAtom == 0)
{
return FALSE;
}
return TRUE;
}
//创建主窗口
HWND CreateMain(LPTSTR lpClassName,LPTSTR lpWndName)
{
HWND hWnd = CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,g_hInstance,NULL);
return hWnd;
}
//创建子窗口
HWND CreateChild(LPTSTR lpClassName,LPTSTR lpWndName,HWND hParent)
{
HWND hChild = CreateWindowEx(0,lpClassName,lpWndName,
WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,100,100,200,200,
hParent,NULL,g_hInstance,NULL);
return hChild;
}
//显示窗口
void Display(HWND hWnd)
{
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
}
//消息循环
void Message()
{
MSG nMsg = {0};
while (GetMessage(&nMsg,NULL,0,0))
{
TranslateMessage(&nMsg);
DispatchMessage(&nMsg);
}
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
g_hInstance = hInstance;
Register("Main",WindowProc);
HWND hWnd = CreateMain("Main","Window");
HWND hChile1 = CreateChild("Main","C1",hWnd);
HWND hChile2 = CreateChild("Main","C2",hWnd);
Display(hWnd);
MoveWindow(hChile1,300,100,200,200,TRUE);
MoveWindow(hChile2,500,100,200,200,TRUE);
Message();
return 0;
}
运行结果:
为什么会出现两个C2窗口?
因为C1窗口还未更新。
修复方法,只要最小化窗口在恢复就好了。
如图:
PostQuitMessage可以使GetMessage返回0?
从MSDN中可知:当GetMessage函数返回的信息为WM_QUIT时,GetMessage返回值为0,
那么说PostQuitMessage可以向进程抛出退出信息(抛出WM_QUIT)?