/*--
008 编程大师 Win32 API 日常练习。
第 8 个示例是 hellowinC:Windows 程序模型。
c) www.bcdaren.com 编码高手。
#include
lresult callback wndproc (hwnd, uint, wparam, lparam) ;窗口过程-消息函数。
int winapi winmain (hinstance hinstance, hinstance hprevinstance,pstr szcmdline, int icmdshow) pstr 非宽字符串指针字符*
static tchar szappname = text ("hellowin") ;窗口类的名称。
hwnd hwnd ;窗口把手。
msg msg ;消息结构变量 -f1
wndclass wndclass ;窗口类结构变量。
第 1 步:初始化窗口类。
wndclass.style = cs_hredraw | cs_vredraw ;窗口类样式 - 水平和垂直标识符 - been。
更改时,将重新绘制类的所有窗口。
wndclass.lpfnwndproc = wndproc ;窗口处理程序---函数指针。
wndclass.cbclsextra = 0 ;窗口被扩展,cb 表示字节数。
wndclass.cbwndextra = 0 ;窗口实例扩展。
wndclass.hinstance = hinstance ;进程实例句柄。
wndclass.hicon = loadicon (null, idi_application) ;窗口的最小化图标。
wndclass.hcursor = loadcursor (null, idc_arrow) ;窗口鼠标光标。
wndclass.hbrbackground = (hbrush) getstockobject (white_brush);背景颜色。
wndclass.lpszmenuname = null ;窗口菜单。
wndclass.lpszclassname = szappname ;窗口类的名称。
第 2 步:注册窗口类。
if (!registerclass (&wndclass))
messagebox(null, text("注册失败!"),szappname, mb_iconerror);
return 0;
第 3 步:创建一个窗口。
hwnd = createWindow( szappname,窗口类的名称。
text ("创建窗口"),窗口标题。
ws overlappedwindow,窗口样式。
cw usedefault,窗口的初始水平位置。
cw usedefault,窗口的初始垂直位置。
cw usedefault,窗口的宽度,以设备单位表示
cw usedefault,窗口的高度(以设备单位为单位)
null,父窗口的句柄。
null,窗口菜单句柄。
hinstance,程序实例句柄。
null) ;创建参数。
第四步显示和更新窗口。
showwindow (hwnd, icmdshow) ;显示窗口。
updatewindow (hwnd) ;更新窗口。
第 5 步:消息循环。
而 (getMessage (&msg, null, 0, 0)) 消息队列,则消息是。
wm quit 返回 0 退出消息循环。
将 msg 结构返回到 Windows,并将虚拟键消息转换为字符消息。
translatemessage(&msg);
再次将 msg 结构返回到 Windows,并将消息分发给窗口程序。
dispatchmessage(&msg);
msg.wparam 来自指示退出的消息,并将此值返回给系统,从而退出。
return msg.wparam ;
窗口进程。 lresult callback wndproc (hwnd hwnd, uint message, wparam wparam, lparam param)
hdc hdc ;外部环境句柄 (设备上下文句柄) 。
paintstruct ps ;用于绘制应用程序拥有的窗口的工作区。
rect rect ;矩形结构由其左上角和右下角的坐标定义。
switch (message)
case wm create:创建窗口消息。
return 0 ;
case wm paint:重绘窗口消息。
hdc = beginpaint (hwnd, &ps);开始绘图(获取设备环境) - 在本例中为显示。
getclientrect (hwnd, &rect) ;此函数获取窗口工作区的大小。
drawtext (hdc, text ("hello, windows!")、1、&rect、-1 表示零字符串。
dt_singleline | dt_center | dt_vcenter) ;绘图格式:指定。
矩形文本显示在水平和垂直居中的单行上。
endpaint (hwnd, &ps) ;在指定窗口中标记绘图的结束。
return 0 ;
case wm destroy:退出消息循环。
postquitmessage (0) ;向系统指示线程已请求终止(退出)。
return 0 ;
“调用操作系统默认窗口”过程为应用程序未处理的任何窗口消息提供默认处理。
return defwindowproc (hwnd, message, wparam, lparam) ;
结果:“注释”图标、标题和“系统”菜单都位于标题栏中,标题栏下方的区域是“客户端”区域。
图2-1 创建窗口。
在hellowin中C程序的功能是绘制一个自定义窗口,并在窗口工作区输出文本字符串“hello, Windows!””。
该程序分为两部分:主程序 WinMain 和窗口过程 WndProc。
主程序
winmain 函数。
winmain函数是Windows窗口程序的入口函数,而console程序的入口函数是main函数。 创建项目时,会选择桌面应用程序,因此“项目属性”->“链接器”-“>系统”->“子系统”选项默认为“窗口”,如图所示。 当然,如果此选项设置为“未设置”,链接器会根据函数名称“winmain”判断它是一个窗口程序。
2-2 与窗口子系统选项。
Winmain函数原型:
int winapi winmain (hinstance hinstance, hinstance hprevinstance,pstr szcmdline,int icmdshow);
它也可以是: int winapi winmain( hinstance hinstance, hinstance hprevinstance,lpstr lpcmdline, int ncmdshow);
函数的返回值为 int 类型。 返回值 0 表示正常结束,非 0 值表示异常结束。
函数调用约定为:winapi,即 stdcall 调用约定。
参数 1 hinstance hinstance:是当前进程的句柄,由操作系统在创建和初始化进程时给出。
参数 2 hinstance hprevinstance:上一个进程句柄,是 win16 系统遗留的参数。 Win16 是一个 16 位单任务实模式操作系统,该参数用于判断上一个进程是否已经结束,只有当上一个进程结束时,才能创建当前进程。
参数 3 pstr szcmdline:是指向包含命令行参数的以 null 结尾的字符串的长指针。
参数 4 int icmdshow:一个整数值,用于确定主窗口的显示方式。 它可以是这样的:
SW 隐藏:隐藏窗口,并激活另一个窗口。
SW 最大化:最大化窗口,然后激活它。
SW 最小化:最小化窗口并激活下一个顶级窗口。
SW RESTORE:激活并显示窗口。 如果窗口最小化或最大化,窗口将恢复到其原始大小和位置。
SW show:以当前大小和位置显示并激活窗口。
SW showdefault:根据启动应用程序时传递给 createProcess 函数的 startupinfo 结构的 WSHOWWewWindowField 设置第一个显示窗口的状态。
SW showmaximized:最大化窗口并激活它。
SW showminimized:最小化窗口,然后激活它。
SW showminnoactive:最小化窗口,但不要激活它。
SW showna:以当前状态显示窗口,但不激活它。
SW shownoactivate:以最接近的大小和位置显示窗口,但不激活它。
SW shownormal:与SW恢复类似,它根据窗口的默认位置和大小显示和激活。
默认值为正常大小的显示窗口。
winmain 函数中需要定义 4 个变量:
static tchar szappname = text ("hellowin") ;定义窗口类名称,该名称通常也是进程的名称。
hwnd hwnd ;定义一个窗口句柄,通过该句柄可以操作窗口。
msg msg ;定义消息结构变量。
wndclass wndclass ;定义窗口类结构变量。 窗口类在上一节中已经解释过了,所以我不会重复它们。
如果我们想查看相关的帮助信息,我们可以选择它,然后按F1键查看MSDN相关信息。 您也可以选择它,点击鼠标右键,快速掌握定义或进入定义,vs操作非常方便。
主程序创建窗口的五个步骤:
第 1 步:初始化窗口类。 如果要创建自定义窗口,则必须指定有关该窗口的信息并将其传递给操作系统。 简单来说,就是初始化窗口类结构体的字段。 如果不需要或没有字段,可以将其设置为 null。 但是,窗口样式、窗口过程和窗口类名字段是必填字段。
第 2 步:注册窗口类。 初始化新的窗口类后,我们需要向 WinodWS 系统注册该窗口类并调用 API 函数 RegisterClass。
第 3 步:调用 createwindow 函数创建窗口。
第 4 步:显示和更新窗口。
showwindow (hwnd, icmdshow) ;显示窗口。
updatewindow (hwnd) ;更新窗口。
第 5 步:循环消息。
如果消息为 wm quit,则返回 0 并退出消息循环。
while (getmessage (&msg, null, 0, 0))
将 msg 结构返回到 Windows,并将虚拟键消息转换为字符消息。
translatemessage(&msg);
再次将 msg 结构返回到 Windows,并将消息分发给窗口程序。
dispatchmessage(&msg);
消息循环是一个 while 循环结构,它调用 getmessage 函数从窗口消息队列中获取消息,如果消息为 wm quit 退出消息循环,则返回 0。 否则,translatemessage 函数和 dispatchmessage 函数会处理它。
主程序创建窗口的五个步骤是强制性的、固定的,可以用作 Windows 程序的模板。 在大多数情况下,只需复制它并使用它就可以了。 如果要添加子窗口或处理控制消息或菜单快捷方式消息,可以稍作更改。 Windows 编程的基础知识比看起来要简单得多。
窗口进程。
窗口进程负责处理 Windows 系统发送到窗口的各种消息。
lresult callback wndproc (hwnd hwnd, uint message,wparam wparam, lparam lparam);
我们会发现,窗口进程的四个参数是 msg 消息结构的前四个字段。 这是 Windows 操作系统传递的消息参数。
参数 hwnd:当前窗口的句柄。 用于标识窗口或应用程序子窗口的唯一标识符。
消息:描述窗口需要处理的消息类型,如wm paint(窗口需要重绘)、wm destroy(窗口即将被销毁)等。
参数 wparam:是特定于消息的附加信息。 内容将根据特定的消息类型而有所不同。
参数 lparam: 也是特定于消息的附加信息。 内容将根据特定的消息类型而有所不同。
返回值 lresult 是消息处理完毕后返回的信息,返回信息因消息类型而异。
每当发生事件(如鼠标单击、键盘击键、计时器事件等)时,Windows 都会向相应的窗口发送消息,并通过 WNDPROC 函数处理该消息。
对于大多数消息,一旦 wndproc 处理完它们,它应返回 0。 对于某些消息,例如 WM Create 和 WM Paint,返回的值可能包含某些信息。 所有这些信息都在每条消息的具体说明中进行了详细说明。
如果消息没有被 wndproc 处理,那么你应该调用 Windows 系统默认窗口过程的 defwindowproc 函数,让系统以默认方式处理它。 绝大多数消息由 defwindowproc 函数处理。
WNDPROC 的调用约定是 callback,与 WinAPI 相同,并且与 stdcall 调用约定相同。 之所以使用callback,顾名思义,wndproc 是一个 ** 函数,即 Windows 系统调用 wndproc 来处理各种消息。
wndproc 窗口进程主要包含一个 switch 结构,根据不同的消息 ID 分别处理,处理后直接返回 0;返回。 默认情况下,其他未处理的消息将留给 defwindowproc 按原样处理。
接下来,我们将分解这个模板程序,一步一步地实现窗口创建过程,这样我们就可以分析窗口实现过程了。