鱼C论坛

 找回密码
 立即注册
查看: 5224|回复: 19

[技术交流] windows窗口创建过程对应API解释(取自小甲鱼老师的API档案)

[复制链接]
发表于 2014-11-20 18:29:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 freeparty 于 2015-6-19 12:53 编辑

一个个的查太痛苦了,所以作为新手我把他们一个个摘录到程序后面的注解里了,有需要的可以去看看,不过需要我们先将代码打上5遍之后才这样做,不要问我为什么,小甲鱼老师是这样说的。这样对于入门所需要了解的函数能够更快的寻找到吧 ,在这里先感谢一下我们的小甲鱼老师
  1. #include<windows.h>

  2. LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
  3. /*
  4. Windows 的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数)。
  5. 回调函数需要到函数最后面几行找
  6. */

  7. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,PSTR szCmdLine,int iCmdShow)
  8. /*
  9. hInstance:应用程序当前事例的句柄。
  10. hPrelnstance:应用程序的先事例的句柄。对于同一个程序打开两次,出现两个窗口第一次打开的窗口就是先前实例的窗口。对于一个32的位程序,该参数总为NULL。
  11. lpCmdLine:指向应用程序命令行的空字符串的指针,不包括函数名。获得整个命令行,参看GetCommandLine。
  12. iCmdShow:指明窗口如何显示(是隐藏还是显示,有没有最大化按钮之类的)。取值可以参考MSDN

  13.   这里我相信有一个词大家好应该比较陌生,句柄(HANDLE)是吧。下面我就来简单的说下
  14. 句柄其实就是Windows系统中一个东西的唯一标识。就是系统中有很多运行的程序或者资源之类的,为了更好的管理使用,
  15. Windows系统给它们每人一个ID一样。懂得网页制作的人应该知道网页中各个元素的ID吧,网页的ID如果重复话可能出现错误。
  16. 那么系统的句柄会不会有相同的,那是肯定不会有的了,就和我们的学号一样,系统自动分配每一个模块的句柄,是不会相同的了。
  17.   */
  18. {
  19.         static        TCHAR szAppName[] = TEXT("开始坑爹之旅");
  20.         HWND hwnd;
  21.         MSG msg;
  22.         WNDCLASS wndclass;
  23. /*在创建应用程序窗口之前,必须调用 RegisterClass 函数来注册窗口类。
  24. 该函数只需要一个参数,即指向 WNDCLASS 窗口类的指针。因为 WNDCLASS 类包含了窗口所拥有的基本属性。
  25.         结构原型:
  26. typedef struct tagWNDCLASSW {
  27.     UINT        style;
  28.     WNDPROC     lpfnWndProc;
  29.     int         cbClsExtra;
  30.     int         cbWndExtra;
  31.     HINSTANCE   hInstance;
  32.     HICON       hIcon;
  33.     HCURSOR     hCursor;
  34.     HBRUSH      hbrBackground;
  35.     LPCWSTR     lpszMenuName;
  36.     LPCWSTR     lpszClassName;
  37. } WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
  38.   成员 含义
  39. style 指定窗口类型,各种“类风格”(详见下方↓)可以使用按位或操作符组合起来
  40. lpfnWndProc 指定窗口过程(必须是回调函数)
  41. cbClsExtra 预留的额外空间,一般为 0
  42. cbWndExtra 预留的额外空间,一般为 0
  43. hInstance 应用程序的实例句柄
  44. hIcon 为所有基于该窗口类的窗口设定一个图标
  45. hCursor 为所有基于该窗口类的窗口设定一个鼠标指针
  46. hbrBackground 指定窗口背景色
  47. lpszMenuName 指定窗口菜单
  48. lpszClassName 指定窗口类名 */

  49.         wndclass.style = CS_HREDRAW;
  50.         wndclass.lpfnWndProc = WndProc;
  51.         wndclass.cbClsExtra = 0;
  52.         wndclass.cbWndExtra = 0;
  53.         wndclass.hInstance = hInstance;
  54.         wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
  55.         wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
  56.         wndclass.hbrBackground = (HBRUSH)GetStockObject(COLOR_CAPTIONTEXT);      //背景色
  57.         wndclass.lpszMenuName = NULL;
  58.         wndclass.lpszClassName = szAppName;


  59.         if(!RegisterClass(&wndclass))
  60.         {
  61.         
  62.                 MessageBox(NULL,TEXT("这个程序无法执行"),szAppName,MB_OK);
  63.                 return 0;
  64.         }


  65.         hwnd =CreateWindow(szAppName,
  66.                 TEXT("开始坑爹了"),
  67.                 WS_OVERLAPPEDWINDOW,
  68.                 CW_USEDEFAULT,
  69.                 CW_USEDEFAULT,
  70.                 CW_USEDEFAULT,
  71.                 CW_USEDEFAULT,
  72.                 NULL,
  73.                 NULL,
  74.                 hInstance,
  75.                 NULL);

  76.         ShowWindow(hwnd,iCmdShow);   //显示窗口      
  77.         UpdateWindow(hwnd);                                //更新窗口

  78.         while(GetMessage(&msg,NULL,0,0))
  79.                 /*
  80. 注释:_In_ 说明该参数是输入的,_opt_ 说明该参数是可选参数。
  81. BOOL WINAPI GetMessage(
  82.   _Out_     LPMSG lpMsg,
  83.   _In_opt_  HWND hWnd,
  84.   _In_      UINT wMsgFilterMin,
  85.   _In_      UINT wMsgFilterMax
  86. );

  87. lpMsg 指向 MSG 结构的指针
  88. hWnd        1. 需要检索消息的窗口的句柄,该窗口必须属于当前线程
  89.                 2. 当其值是 NULL 时,将检索所有的当前线程的窗口消息和线程消息
  90.                 3. 当其值是 -1 时,只检索当前线程消息
  91. wMsgFilterMin 指定被检索的最小消息值的整数
  92. wMsgFilterMax 指定被检索的最大消息值的整数

  93. 返回值:
  94. 1. 如果函数取得 WM_QUIT 之外的其他消息,返回非零值;
  95. 2. 如果函数取得 WM_QUIT 消息,返回值是零;
  96. 3. 如果出现了错误,返回值是 -1。

  97. */
  98.         {
  99.                 TranslateMessage(&msg);
  100. /*
  101. TranslateMessage 函数将虚拟键消息转换为字符消息,字符消息被寄送到当前线程的消息队列里。
  102. 当下一次线程调用函数 GetMessage 或 PeekMessage 时被读出。
  103. BOOL WINAPI TranslateMessage(  _In_  const MSG *lpMsg);
  104. lpMsg 指向含有消息的 MSG 结构的指针
  105. 返回值:
  106. 1. 如果消息被转换(字符消息被寄送到当前线程的消息队列里)则返回非零值;
  107. 2. 如果消息是 WM_KEYDOWN,WM_KEYUP WM_SYSKEYDOWN 或 WM_SYSKEYUP,返回非零值,不考虑转换;
  108. 3. 如果消息没被转换(字符消息没被寄送到调用线程的消息队列里)则返回值是零。
  109.                 */

  110.                 DispatchMessage(&msg);
  111. /*
  112. DispatchMessage 函数分派一个消息给窗口过程(回调函数),通常该消息从 GetMessage 函数获得。Windows 的控制权在该函数交给了应用程序。
  113. LRESULT WINAPI DispatchMessage(  _In_  const MSG *lpmsg);
  114. lpmsg 指向含有消息的 MSG结构 的指针
  115. 返回值:
  116. 1. 返回值是窗口过程返回的值;
  117. 2. 尽管返回值的含义依赖于被分派的消息,但返回值通常被忽略。
  118. 备注:
  119. 1. MSG 结构必须包含有效的消息值。
  120. 2. 如果参数 lpmsg 指向一个 WM_TIMER 消息,并且 WM_TIMER 消息的参数 lParam 不为 NULL,则调用 lParam 指向的函数,而不是调用窗口程序。
  121. */
  122.         }
  123.         return msg.wParam;


  124. }

  125. LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  126. {
  127. /*
  128.         PAINTSTRUCT 结构包含一些窗口过程用来对客户区进行绘制的信息。
  129.         typedef struct tagPAINTSTRUCT {
  130.         HDC  hdc;
  131.         BOOL fErase;
  132.         RECT rcPaint;
  133.         BOOL fRestore;
  134.         BOOL fIncUpdate;
  135.         BYTE rgbReserved[32];
  136. }        PAINTSTRUCT, *PPAINTSTRUCT;

  137. 成员 含义
  138. hdc                                用于绘制的设备环境句柄
  139. fErase                        1. 表示背景是否必须擦除,如果为非零值则擦除背景,否则不擦除背景
  140.                                 2. 如果创建窗口类的时候没有设置背景画刷,则负责擦除背景
  141. rcPaint                        一个 RECT 结构,指定左上角和右下角的坐标确定一个要绘制的矩形范围
  142. fRestore                系统保留
  143. fIncUpdate                系统保留
  144. rgbReserved                系统保留  
  145.         */        
  146.         HDC hdc;
  147.         PAINTSTRUCT ps;                        //声明一个PAINTSTRUCT 结构变量ps
  148.         RECT rect;
  149.         /*
  150.         RECT 结构定义了一个矩形的左上角和右下角的坐标。
  151.         typedef struct _RECT {
  152.         LONG left;      指定矩形左上角的 x 坐标
  153.         LONG top;       指定矩形左上角的 y 坐标
  154.         LONG right;     指定矩形右下角的 x 坐标
  155.         LONG bottom;    指定矩形右下角的 y 坐标
  156. }        RECT, *PRECT;

  157.         */

  158.                 switch (message)
  159.         {
  160.                 case WM_PAINT:                //WM_PAINT 0x000F 要求一个窗口重绘自己
  161.                 hdc = BeginPaint(hwnd, &ps);        
  162.         /*
  163.         BeginPaint 函数为指定窗口进行绘画工作的准备,并用将和绘画有关的信息填充到一个 PAINTSTRUCT 结构中。

  164.         HDC BeginPaint(
  165.          _In_   HWND hwnd,
  166.          _Out_  LPPAINTSTRUCT lpPaint
  167.         );
  168.         hwnd 需要重新绘制的窗口句柄
  169.         lpPaint 指向 PAINTSTRUCT 结构的指针,用于存放绘画相关的信息         
  170.         返回值:
  171.         1. 如果函数成功,返回值是指定窗口的“显示设备描述表”句柄;
  172.         2. 如果函数失败,返回值是 NULL,表明没有得到显示设备的内容。
  173.         备注:
  174.         1. BeginPaint 函数自动设置显示设备内容的剪切区域,而排除任何更新区域外的区域。
  175.         该更新区域可以通过 InvalidateRect 或 InvalidateRgn 函数设置,也可以是系统在改变大小、移动、创建、滚动后设置的,或者其他的影响客户区的操作来设置的。
  176.         2. 如果更新区域被标记为可擦除的,BeginPaint 发送一个 WM_ERASEBKGND 消息给窗口。
  177.         3. 一个应用程序除了响应 WM_PAINT 消息外,不应该调用 BeginPaint。
  178.         4. 每次调用 BeginPaint 都应该有相应的 EndPaint 函数。
  179.         5. 如果被绘画的客户区中有一个 caret(caret:插入符。是窗口客户区中的一个闪烁的线,块,或位图。插入符通常表示文本或图形将被插入的地方。
  180.         即一闪一闪的光标),BeginPaint 自动隐藏该符号,而保证它不被擦除。
  181.         6. 如果窗口类有一个背景刷,BeginPaint 使用这个刷子来擦除更新区域的背景

  182.     */
  183.                 GetClientRect(hwnd, &rect);
  184.         /*GetClientRect 函数用于获取窗口客户区的坐标,客户区坐标指定客户区的左上角和右下角。
  185.         由于客户区坐标是相对窗口客户区的左上角而言的,因此左上角坐标为(0,0)
  186.         BOOL WINAPI GetClientRect(
  187.          _In_   HWND hWnd,
  188.          _Out_  LPRECT lpRect
  189.         );
  190.         hWnd 需要获取客户区坐标的窗口句柄
  191.         lpRect        1. 指向 RECT 结构的指针,该结构有四个成员,分别为 left、top、right 和 bottom
  192.                         2. GetClientRect 将这四个成员设定为窗口显示区域的尺寸。
  193.                            left 和 top 字段通常设定为 0,right 和 bottom 字段设定为显示区域的宽度和高度(像素点数)
  194.                 */
  195.                 DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
  196.                         DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  197.                 /*
  198.                 DrawText 函数在指定的矩形里写入格式化的正文,根据指定的方法对正文格式化(扩展的制表符,字符对齐、折行等)。
  199.                 int DrawText(
  200.                  _In_     HDC hDC,
  201.                  _Inout_  LPCTSTR lpchText,
  202.                  _In_     int nCount,
  203.                  _Inout_  LPRECT lpRect,
  204.                  _In_     UINT uFormat
  205.                 );
  206.                 hDC 指定“显示设备描述表”句柄
  207.                 lpchText 1. 指向将被写入的字符串的指针,如果参数 nCount 是 -1,则字符串必须是以 \0 结束的
  208.                                  2. 如果 uFormat 包含 DT_MODIFYSTRING,则函数可为此字符串增加 4 个字符,存放字符串的缓冲区必须足够大,能容纳附加的字符
  209.                 nCount   1. 指向字符串中的字符数
  210.                                  2. 如果 nCount 为 -1,则 lpchText 指向的字符串被认为是以 \0 结束的,DrawText 会自动计算字符数
  211.                 lpRect 指向 RECT 结构的指针,其中包含文本将被置于其中的矩形的信息(按逻辑坐标)
  212.                 uFormat  1. 指定格式化文本的方法
  213.                                  2. 此参数可以通过指定下列标志或标志的组合         
  214.                 返回值:
  215.                 1. 如果函数调用成功,返回值是正文的高度(逻辑单位);
  216.                 2. 如果指定了 DT_VCENTER 或 DT_BOTTOM,返回值是 lpRect -> top 到绘制的正文的底部的偏移值;
  217.                 3. 如果 函数调用失败,返回值是 0。
  218.                 备注:
  219.                 1. 函数 DrawText 用设备环境中的字体选择、正文颜色和背景颜色来写正文。
  220.                 2. DrawText 裁剪正文,使之不会出现在指定矩形的外面,除非指定了 DT_NOCLIP。
  221.                 3. 除非使用 DT_SINGLELINE 格式化,否则其余的格式都认为正文有多行。
  222.                 4. 如果选择的字体对指定的矩形而言太大,DrawText 并不会试图去换成一种小字体。
  223.                 5. 设备环境的正文对齐方式必须包括 TA_LEFT, TA_TOP 和 TA_NOUPDATECP 标志。
  224.                 */
  225.                 EndPaint(hwnd, &ps);
  226.                 /*EndPaint 函数标记指定窗口的绘画过程结束。
  227.                 BOOL EndPaint(
  228.                 _In_  HWND hWnd,
  229.                  _In_  const PAINTSTRUCT *lpPaint
  230.                  );
  231.                  hWnd 已经被重新绘制的窗口句柄
  232.                 lpPaint 指向 PAINTSTRUCT 结构的指针,用于存放绘画相关的信息(该指针在调用 BeginPaint 时被赋值)
  233.                 */
  234.                 return 0;
  235.                 case WM_DESTROY:                //WM_DESTROY 0x0002 一个窗口被销毁
  236.                 PostQuitMessage(0);
  237.                 /*PostQuitMessage 函数向系统表明有个线程有终止(退出)请求。
  238.                 这个函数通常用来响应 WM_DESTROY 消息。
  239.                 VOID WINAPI PostQuitMessage(
  240.                  _In_  int nExitCode
  241.                 );
  242.                 nExitCode 指定应用程序的退出代码,此值被用作 WM_QUIT 消息的 wParam 参数
  243.                 返回值:该函数没有返回值。        
  244.                 备注:
  245.                 1. PostQuitMessage 函数的功能是发送一个 WM_QUIT 消息给线程的消息队列并立即返回。
  246.                 2. 当线程从消息队列里取得 WM_QUIT 消息时,应当退出消息循环并将返回系统,
  247.                 返回给系统的退出值必须是消息 WM_QUIT 的 wParam 参数(所以 WinMain 函数的返回值是 msg.wParam)。
  248. */
  249.                 return 0;
  250.         }

  251.   return DefWindowProc(hwnd, message, wParam, lParam);
  252.   /*DefWindowProc 函数调用缺省的窗口过程来处理那些窗口过程没有处理的任何消息,该函数是为了确保每个消息都被处理。
  253.         DefWindowProc 函数传入和窗口过程同样的参数。

  254.   LRESULT WINAPI DefWindowProc(
  255.   _In_  HWND hWnd,
  256.   _In_  UINT Msg,
  257.   _In_  WPARAM wParam,
  258.   _In_  LPARAM lParam
  259. );
  260. hWnd           指定接收消息的窗口句柄
  261. Msg                1. 消息的标识符,由于数值不便于记忆,所以 Windows 将消息对应的数值定义为 WM_XXX 宏的形式
  262.                 2. 应用程序消息只能使用低 16 位,高 16 位被系统保留
  263.                 3. 传送门:Windows 常用消息及含义
  264. wParam           指定消息的附加消息,确切的含义取决于消息成员的值
  265. lParam           指定消息的附加消息,确切的含义取决于消息成员的值

  266.   返回值就是消息处理结果,它取决于发送的消息
  267. */

  268. }
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
freeparty + 5 + 5 支持楼主

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-11-20 18:38:33 | 显示全部楼层
自己先坐个沙发
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-11-20 19:57:13 | 显示全部楼层

回帖奖励 +2 鱼币

支持学习了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-12-1 20:04:07 | 显示全部楼层

回帖奖励 +2 鱼币

激动人心  无法言表
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2014-12-6 23:51:22 | 显示全部楼层

回帖奖励 +2 鱼币

支持学习啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-12-13 15:29:56 | 显示全部楼层

回帖奖励 +2 鱼币

哈哈,开始学的时候我也把注释全写了,发现还挺有效的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-12-13 18:19:37 | 显示全部楼层

回帖奖励 +2 鱼币

辛苦楼主。。我也照着敲了好多遍,视频重复看了又看。还是没有楼主理解得如此透,学习了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-12-15 15:30:45 | 显示全部楼层

回帖奖励 +2 鱼币

很详细,很强大
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-1-31 14:09:13 | 显示全部楼层

回帖奖励 +2 鱼币

{:1_1:}拿下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-2-13 10:27:01 | 显示全部楼层

回帖奖励 +2 鱼币

哪里透明了???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-13 10:51:35 | 显示全部楼层

回帖奖励 +2 鱼币

C++还好一些,要用C#搞这些api能把人郁闷死。:huffy:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-22 22:31:25 | 显示全部楼层
学习了:big
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-23 14:07:48 | 显示全部楼层
学习了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-27 19:19:33 | 显示全部楼层
有点乱,不过还是来学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-13 14:31:12 | 显示全部楼层
谢谢分享!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-13 16:46:46 | 显示全部楼层
:lol:很详细
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-13 17:55:09 | 显示全部楼层
支持楼主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-10-12 20:32:26 | 显示全部楼层
支持啊,基本把所有的都注释了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-10-14 09:20:17 | 显示全部楼层
学习了,里面有些东西一直没有搞懂。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 16:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表