当前位置:   article > 正文

win32Day06:控件_torrentkitty

torrentkitty

1.什么是控件?

  1. 控件是具备特殊功能的窗口,并且有模板。
  2. 控件的特性:一定是子窗口 和创建主窗口一样,都是使用CreateWindow函数来创建。
    1. (控件这种)子窗口和主窗口的区别:
      1. 风格不同
      2. 控件不需要注册,控件的窗口类是程序事先注册好的。(用术语说叫控件有模板,例如静态框的窗口类名叫Static,按钮的窗口类名叫Button)
  3. 所有的控件都必须有两个风格WS_CHILD表明这个窗口是子窗口 WS_VISIBLE表示这个窗口可以看见。所以说,不管写什么控件,不管三七二十一先把这两个风格写上。

2.基本控件

  1.  静态框 static
    1. 静态文本框:
      1. 风格需要考虑:
        1. 文字是显示在一个矩形区域之中,那么是靠左(SS_LEFT)还是靠右(SS_RIGHT)还是居中(SS_CENTER)呢?
        2. 矩形框的颜色:灰色(SS_GRAYRECT)、白色(SS_WHITERECT)还是黑色(BLACKRECT)
        3. 矩形边框的颜色:灰色(SS_GRAYFRAME)黑色(SS_BLACKFRAME)还是白色(SS_WHITEFRAME);
        4. 如何设置字体:CreateFont创建字体
          1. HFONT CreateFont(
          2. int cHeight, //字体的逻辑高度
          3. int cWidth, //字体的逻辑宽度
          4. int cEscapement, //指定移位向量相对X轴的偏转角度
          5. int cOrientation, //指定字符基线相对X轴的偏转角度
          6. int cWeight, //设置字体粗细程度
          7. DWORD bItalic, //是否启用斜体
          8. DWORD bUnderline, //是否启用下划线
          9. DWORD bStrikeOut, //是否启用删除线
          10. DWORD iCharSet, //指定字符集
          11. DWORD iOutPrecision, //输出精度
          12. DWORD iClipPrecision, //剪裁精度
          13. DWORD iQuality, //输出质量
          14. DWORD iPitchAndFamily, //字体族
          15. LPCSTR pszFaceName //字体名);

          设置字体仍然用SelectObject()补上节课SelectObject 怎么用。

        5. 静态文本框举例:

          1. void onCreate(HWND hwnd){
          2. CreateWindow("Static","速度(km/h)",WS_CHILD|WS_VISIBLE|SS_CENTER,50,50,100,30,hwnd,(HMENU)1001,g_hInst,NULL);
          3. CreateWindow("Static","速度(m/s)",WS_CHILD|WS_VISIBLE|SS_CENTER,50,100,100,30,hwnd,(HMENU)1001,g_hInst,NULL);
          4. CreateWindow("Static","速度(s/100m)",WS_CHILD|WS_VISIBLE|SS_CENTER,50,150,100,30,hwnd,(HMENU)1001,g_hInst,NULL);
          5. }

           

    2. 静态位图框:
      1. 添加资源 Bitmap 其实建议导入为ICON类型的资源。这样之后做图标变换方便点。
      2. 修改位图资源,并得到这些资源的ID
        1. CreateWindow(
        2. "Static",
        3. "#130",//位图ID
        4. WS_CHILD|WS_VISIBLE|SS_BITMAP,
        5. 30,30,
        6. 150,30,//虽然位图资源有自己宽高,但是这里我们可以修改它的宽高
        7. hwnd,
        8. (HMENU)1002,
        9. g_hInst,NULL)
        CreateWindow(L"Static",L"#129", WS_CHILD | WS_VISIBLE | SS_BITMAP, 30, 30, 200, 200,hWnd,(HMENU)1002, hInst,NULL);

        如何通过设置静态文本框的消息处理函数呢?当我们点击 静态文本框时,静态文本框产生消息和菜单项产生的消息完全相同都是WM_COMMAND。消息处理函数收到WM_COMMAND消息后,首先通过高低WORD提取出附加消息中的ID和EVENT(单击STN_CLICK还是双击STN_DBLCLK),这样就知道触发了谁的什么事件了。

      3. 举例:假设我们已经插入了一个静态文本框1001和一个静态位图框1002。现在要实现通过单击静态文本框,静态位图框的内容就会自动更换成我们预先设定好的样子。请问消息处理函数应该怎样写?

        1. case WM_COMMAND:{
        2. int wmId = LOWORD(wParam);
        3. int wmEvent = HIWORD(wParam);
        4. switch(wmId){
        5. case 1001:
        6. if(wmEvent == STN_CLICKED){//如果是单击事件
        7. //1.加载新图标到窗口实例程序中
        8. HICON hIcon1 = LoadIcon(hInst,MAKEINTERSOURCE(IDI_ICON1));
        9. HWND hStaticWnd = GetDlgItem(hwnd,1002);
        10. //3.向控件发送消息来操作控件
        11. SendMessage(hStaticWnd,STM_SETICON,(WPARAM)hIcon1,NULL);
        12. /*表示给hStaticWnd发送信息
        13. 消息内容为:STM_SETICON设置icon
        14. 附加消息为:hIcon1表示设置为这个icon
        15. */
        16. }else if(wmEvent == STN_DBLCLK){
        17. //1.加载新图标到窗口实例程序中
        18. HICON hIcon1 = LoadIcon(hInst,MAKEINTERSOURCE(IDI_ICON2));
        19. HWND hStaticWnd = GetDlgItem(hwnd,1002);
        20. //3.向控件发送消息来操作控件
        21. SendMessage(hStaticWnd,STM_SETICON,(WPARAM)hIcon2,NULL);
        22. /*表示给hStaticWnd发送信息
        23. 消息内容为:STM_SETICON设置icon
        24. 附加消息为:hIcon1表示设置为这个icon
        25. */
        26. }
        27. }
        28. }

        特别注意:GetDlgItem这个函数非常重要。get dialogbox  item 通过ID得到对话框中的一个元素的句柄。但是如果仅仅这样写,并不会达到预想的效果,还需要给静态文本框添加一个风格SS_NOTIFY 通知通告。这样点击静态文本框后,才会触发通知消息。

      4. SendMessage()通过给控件发送特定的消息来操控控件!

  2. 按钮 Button
    1. 普通按钮
       CreateWindow("Button","单位换算",WS_CHILD|WS_VISIBLE|SS_CENTER,300,50,100,30,hwnd,(HMENU)2001,g_hInst,NULL);

       

    2. 单选按钮:在普通按钮的基础上加一个风格BS_RADIOBUTTON就可以。但是这样做出来的单选按钮是无法选中的。要想能选,必须加BS_AUTORADIOBUTTON.。
      1. CreateWindow("Button","选项1",WS_CHILD|WS_VISIBLE|SS_CENTER|BS_RADIOBUTTON,
      2. 300,50,100,30,hwnd,(HMENU)2001,g_hInst,NULL);

      注意事项:

      1. BS_RADIOBUTTON是手动版本,需要在消息处理函数中写代码设置状态切换

      2. BS_AUTORADIOBUTTON 只是“显示”自动版本,即你可以看到那个被选中,但是你要想在程序中知道那个被选中还是需要手动写代码。

      3. 分组:如果不作设置,所有的单选按钮为一组。即这么多单选按钮,只能有一个被选中。如果想设置分组,需要添加一个风格,即WS_GROUP.即从第一个设置WS_GROUP的按钮直到遇到下一个WS_GROUP为一组。即WS_GROUP设置一组的第一个。

        1. CreateWindow("Button","选项1",WS_CHILD|WS_VISIBLE|SS_CENTER|BS_RADIOBUTTON|WS_GROUP,
        2. 300,50,100,30,hwnd,(HMENU)2001,g_hInst,NULL);
        3. CreateWindow("Button","选项2",WS_CHILD|WS_VISIBLE|SS_CENTER|BS_RADIOBUTTON,
        4. 300,50,100,30,hwnd,(HMENU)2002,g_hInst,NULL);
        5. //1,2为一组
        6. CreateWindow("Button","选项3",WS_CHILD|WS_VISIBLE|SS_CENTER|BS_RADIOBUTTON|WS_GROUP,
        7. 300,50,100,30,hwnd,(HMENU)2003,g_hInst,NULL);
        8. CreateWindow("Button","选项4",WS_CHILD|WS_VISIBLE|SS_CENTER|BS_RADIOBUTTON,
        9. 300,50,100,30,hwnd,(HMENU)2004,g_hInst,NULL);
        10. //3,4为一组

           

      4. 单选按钮也有分隔栏(分组框)加一个风格BS_GROUPBOX。分组框的大小应该足够大,可以包下所有的单选按钮。

        1. CreateWindow("Button","分组框",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
        2. 300,50,500,500,hwnd,(HMENU)2001,g_hInst,NULL);

        用单选框可以做一个问卷系统,或者做一个考试系统。可以判断用户做题的对错,如果用户做错了,就把答案弹到一个文本框中。

      5. 如何控制单选按钮?

        1. 首先,获得单选按钮的句柄 GetDlgItem

        2. 给单选按钮发送消息来控制单选按钮

          1. 设置选中BM_SETCHECK 还是获取选中的状态BM_GETSTATE

          2. 设置选中(WPARAM)BST_CHECKED还是设置不要选中(WPARAM)BST_UNCHECKED 这条需要添加到wparam中。

        3. 例如:

          1. case WM_COMMAND:
          2. {
          3. int wmId = LOWORD(wParam);
          4. int wmEvent = HIWORD(wParam);
          5. // 分析菜单选择:
          6. switch (wmId)
          7. {
          8. case 2001: {
          9. HWND hC = GetDlgItem(hWnd, 2003);
          10. SendMessage(hC, BM_SETCHECK, BST_CHECKED, NULL);
          11. break;
          12. }
          13. }
          14. }

           

    3. 复选框:在普通按钮的风格基础上加一个BS_AUTOCHECKBOX。可以用来做多选题。如何知道复选框是否被选中呢?还是用int ret = SendMessage(复选框句柄,BM_GETCHECK,BST_CHECKED,NULL);如果被选中了ret的值大于0,否则小于等于0。
    4. 三态复选框:在普通按钮的基础上加一个BS_AUTO3STATE。所谓选中,即黑色选中,灰色,白色没有被选中。
  3. 文本编辑框 Edit:
    1. 获取文本框内容:
      1. HWND hEdit1 = GetDlgItem(hwnd,3001);
      2. char buff[256] ={0};
      3. SendMessage(hEdit1,WM_GETTEXT,(WPARAM)255,(LPARAM)buff);

       

    2. 修改文本框内容:
      1. char buff2[256]="lalalalalal"
      2. SendMessage(hEdit2,WM_SETTEXT,strlen(buff2),(LPARAM)buff2);

      dsa

    3. 怎样给文本框加边框:可以通过给文本框加一个分组框来模拟这个过程。

  4. 组合框  ComboBox:组合框和下拉框的区别,组合框是升级版的下拉框,即组合框既可以在框内输入内容,也可以通过下拉来选择内容。
    1. HWND hComboBox = CreateWindow("ComboBox","组合框",WS_CHILD|WS_VISIBLE|WS_VSCROLL,30,30,300,300,hwnd,(HMENU)8001,g_hInst,NULL);
    2. char buff[256];
    3. for(int i=0;i<7;i++){
    4. memset(buff,0,sizeof(char)*256);
    5. sprintf(buff,"选项%d",i);
    6. SendMessage(hComboBox,CB_ADDSTRING,strlen(buff),(LPARAM)buff);
    7. //给组合框添加选项的消息
    8. }
    9. break;

    其中WS_VSCROLL表示加滚动条。

  5. 下拉式组合框:添加一个风格CBN_DROPDOWN

    1. HWND hComboBoxDrop = CreateWindow("Combobox","组合框",WS_CHILD|WS_VISIBLE|CBN_DROPDOWN|WS_VSCROLL,600,600,300,300,hwnd,(HMENU)8002,g_hInst,NULL);
    2. char buff2[256];
    3. for(int i=0;i<7;i++){
    4. memset(buff2,0,sizeof(char)*256);
    5. sprintf(buff2,"选项%d",i);
    6. SendMessage(hComboBoxDrop,CB_ADDSTRING,strlen(buff2),(LPARAM)buff2);
    7. }
    8. break;

    获取组合框内容和修改组合框内容方法和文本框相同

  6. 下拉框的其他重要事件:

    1. case 6001
    2. if(wmEvent == CBN_SELENDOK){
    3. MessageBox(hwnd,"选择框的选择发生了变化!",NULL,NULL);
    4. }else if(wmEvent == CBN_EDITCHANGE){
    5. MessageBox(hwnd,"选择框的内容编辑发生了变化!",NULL,NULL);
    6. }
    7. break;

     

  7. 下拉框 :只可以通过下拉来选择内容。
  8. 滚动条
  9. 作业:做一个类型于QQ的登录界面。
  1. #include <windows.h>
  2. #include "stdafx.h"
  3. #include "Resource.h"
  4. #include <stdio.h>
  5. #include <cstdio>
  6. #include <string.h>
  7. #include <cstring>
  8. #include <iostream>
  9. using namespace std;
  10. HINSTANCE g_hInstance;
  11. HCURSOR g_hCursor1, g_hCursor2;//光标句柄
  12. MSG msg;//声明一个MSG类型的消息结构体
  13. HANDLE g_hConsole;//定义一个HANDLE类型的全局变量,之后要将命令行窗口句柄赋值给它,命名时养成习惯:如果是全局变量以g_开头命名它。
  14. HMENU hRight;
  15. int flag = 0;
  16. int i = 0;
  17. HDC hBuffDc;
  18. HDC hMemoryDc;
  19. HDC hDc;
  20. HANDLE hBitmap[5];
  21. HANDLE hBitmap1;
  22. int x = 100;
  23. int y = 100;
  24. int n = 1;
  25. int g_count = 0;
  26. string name0 = "move0.bmp";
  27. string name1 = "move1.bmp";
  28. string name2 = "move2.bmp";
  29. string name3 = "move3.bmp";
  30. int wmId;
  31. int wmEvent;
  32. void zhubei() {
  33. //1把背景图放入hBuffDc中
  34. SelectObject(hBuffDc, hBitmap1);
  35. //2把背景图画入memory中
  36. BitBlt(hMemoryDc, 0, 0, 641, 480, hBuffDc, 0, 0, SRCCOPY);
  37. //3把人物图画入memory中
  38. //3.1人物图选入hBuffDc中
  39. SelectObject(hBuffDc, hBitmap[n]);
  40. //3.2人物图画入memory中
  41. BitBlt(hMemoryDc, x, y, 60, 108, hBuffDc, 60 * i, 108, SRCAND);
  42. BitBlt(hMemoryDc, x, y, 60, 108, hBuffDc, 60 * i, 0, SRCPAINT);
  43. i++;
  44. //4 把memory当图片画入hDc中
  45. BitBlt(hDc, 0, 0, 641, 480, hMemoryDc, 0, 0, SRCCOPY);
  46. }
  47. void tietu(HWND hWnd) {
  48. if (i >= 8) i = 0;
  49. hDc = GetDC(hWnd);
  50. //两个兼容DC
  51. hMemoryDc = CreateCompatibleDC(hDc);//用来放人物
  52. hBuffDc = CreateCompatibleDC(hDc);//用来放背景
  53. /*三级缓冲
  54. 先把背景选到hBuffDc中,再把hBuffDc和人物贴到hMemoryDc中,然后把hMemoryDc贴到hDc(屏幕)中
  55. */
  56. //创建兼容位图
  57. HBITMAP hCompatibleBitmap=CreateCompatibleBitmap(hDc, GetSystemMetrics(SM_CXFULLSCREEN), GetSystemMetrics(SM_CYFULLSCREEN));//创建到hDC中,宽高为窗口的宽,窗口的高
  58. //设置兼容位图到memoryDc
  59. SelectObject(hMemoryDc, hCompatibleBitmap);
  60. hBitmap[0] = LoadImage(g_hInstance,name0.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
  61. hBitmap[1] = LoadImage(g_hInstance,name1.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
  62. hBitmap[2] = LoadImage(g_hInstance,name2.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
  63. hBitmap[3] = LoadImage(g_hInstance,name3.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
  64. hBitmap1 = LoadImage(g_hInstance, "bk.bmp", IMAGE_BITMAP, 641, 480, LR_LOADFROMFILE);
  65. zhubei();
  66. /*
  67. SelectObject(hMemoryDc, hBitmap);
  68. //贴到哪里 坐标(x,y) 宽高 从哪里贴,从哪的坐标 贴图方式
  69. BitBlt(hDc, 80, 108,30,108,hMemoryDc,60*i,108, SRCAND);//将下方的黑色图片按位与去贴。那么黑色遇到任何颜色保持黑色。白色遇到任何颜色仍旧是任何颜色
  70. BitBlt(hDc, 80, 108, 30, 108, hMemoryDc, 60 * i, 0, SRCPAINT);//将上方的彩色图像按位或去贴。
  71. i++;
  72. */
  73. /*
  74. 透明贴图先用SRCAND的方式去贴,然后用SRCPAINT的方式去贴
  75. SRCAND 按位与方式,任何东西与上0(黑色)是0(黑色),任何东西与上1(白色)是任何东西自身(不变)。
  76. SRCPAINT 按位或方式去贴,彩色 或 黑色= 彩色 黑色 或 任何东西 =任何东西。
  77. */
  78. }
  79. //写一个windows窗口
  80. //5定义消息处理函数
  81. void OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam) {
  82. #if 0
  83. //一 系统菜单
  84. HMENU hSystemMenu=GetSystemMenu(hWnd, 0);//获取系统菜单句柄
  85. //删除系统菜单项:系统菜单有七项,其中分隔符也算菜单项
  86. for (int i = 0; i < 6; i++) {
  87. DeleteMenu(hSystemMenu, 0, MF_BYPOSITION);//按照索引的方式删除,0表示当前状况的第一个,是变化的
  88. //DeleteMenu(hSystemMenu, 0, MF_BYCOMMAND);//按照下标的方式删除,0表示初期情况下菜单栏的第一个(即分隔符),是固定的。
  89. }
  90. //追加系统菜单项:追加就一定在最后追加
  91. AppendMenu(hSystemMenu, MF_SEPARATOR, 1111, NULL);//第二个参数决定菜单项的样式:分隔符(MF_SEPARATOR)还是字符串,如果第二个参数选分隔符,那么第三个参数就是分隔符的id
  92. AppendMenu(hSystemMenu, MFT_STRING, 1112, L"(ง •_•)ง(M)");//第二个参数如果是字符串,则最后一个参数为字符串的内容。
  93. //这里只能决定菜单的样子,而真正地处理才是关键。
  94. /*真正的处理在消息处理函数中,系统菜单的消息由WM_COMANND消息管理*/
  95. #endif
  96. //二、顶层菜单
  97. HMENU hTopMenu = CreateMenu();//创建顶层菜单,返回顶层菜单的句柄
  98. //创建弹出式菜单
  99. HMENU hChinese = CreatePopupMenu();
  100. HMENU hJapan = CreatePopupMenu();
  101. HMENU hAmerican = CreatePopupMenu();
  102. HMENU hSearch = CreatePopupMenu();
  103. //将弹出式菜单添加到顶层菜单中
  104. AppendMenu(hTopMenu,MF_POPUP,(UINT)hChinese,"国产");//第三个参数需要弹出式菜单的id,我们将句柄强制转化成id类型
  105. AppendMenu(hTopMenu, MF_POPUP, (UINT)hJapan,"日本");
  106. AppendMenu(hTopMenu, MF_POPUP, (UINT)hAmerican,"欧美");
  107. AppendMenu(hJapan, MF_POPUP, (UINT)hSearch,"搜索");
  108. //添加菜单项到弹出式菜单中
  109. //添加到国产中
  110. AppendMenu(hChinese, MF_STRING,2511, "土肥圆矮穷挫");//第三个参数为你设置的这个菜单项的id
  111. AppendMenu(hChinese, MF_STRING, 2512, "艾栗栗");
  112. AppendMenu(hChinese, MF_STRING, 2513, "萌琪琪");
  113. AppendMenu(hChinese, MF_STRING, 2514, "张柏芝艳照门");
  114. //添加到日本中
  115. AppendMenu(hJapan, MF_STRING, 2521, "波多野结衣");//第三个参数为你设置的这个菜单项的id
  116. AppendMenu(hJapan, MF_STRING, 2522, "切换为蔡徐坤");
  117. AppendMenu(hJapan, MF_STRING, 2523, "桃谷绘里香");
  118. AppendMenu(hJapan, MF_STRING, 2524, "桃乃木香奈");
  119. AppendMenu(hJapan, MF_STRING, 2524, "其他");
  120. AppendMenu(hJapan, MF_STRING, 2525, "选中蔡徐坤");
  121. //添加到欧美中
  122. AppendMenu(hAmerican, MF_STRING, 2531, "安洁莉卡");
  123. //添加菜单项到搜索中
  124. AppendMenu(hSearch, MF_STRING, 2541, "搜索番号");
  125. AppendMenu(hSearch, MF_STRING, 2541, "搜索女优");
  126. AppendMenu(hSearch, MF_STRING, 2541, "搜索男优");
  127. //显示顶层菜单
  128. SetMenu(hWnd, hTopMenu);
  129. //获取菜单项句柄,现在只有我自己设置的菜单项的id
  130. HMENU hTemp = GetSubMenu(hJapan, 0);//得到波多野结衣菜单项的句柄
  131. //设置菜单项
  132. EnableMenuItem(hJapan, 2521,MF_GRAYED);//第一个参数为菜单项所在弹出式菜单的句柄,第二参数该菜单项的id,设置菜单项“波多野结衣”为灰色
  133. //三、创建右键菜单
  134. hRight = CreatePopupMenu();
  135. AppendMenu(hRight, MF_STRING, 3001, "打开男人团");
  136. AppendMenu(hRight, MF_STRING, 3002, "打开福利档");
  137. AppendMenu(hRight, MF_STRING, 3003, "打开torrentkitty");
  138. }
  139. //创建控件
  140. void OnCreate1(HWND hWnd) {
  141. //1静态文本框
  142. CreateWindow("Static", "鸡你太美",
  143. WS_CHILD | WS_VISIBLE | SS_CENTER/*左右居中*/ | SS_NOTIFY/*可以被操作*/,//用位运算(按位或)把各个风格组合起来。每个风格宏常量都是一个整数
  144. 700, 700,//坐标
  145. 150, 30,//宽高
  146. hWnd,//父窗口句柄
  147. (HMENU)1001,//自定义该窗口控件的ID
  148. g_hInstance,//窗口应用程序实例句柄
  149. NULL);//附加信息
  150. //2静态位图框
  151. CreateWindow("Static", "#108",//define IDI_SMALL 108
  152. WS_CHILD | WS_VISIBLE | SS_ICON,//用位运算(按位或)把各个风格组合起来。每个风格宏常量都是一个整数
  153. 1000, 700,//坐标
  154. 30, 30,//宽高
  155. hWnd,//父窗口句柄
  156. (HMENU)1002,//自定义该窗口控件的ID
  157. g_hInstance,//窗口应用程序实例句柄
  158. NULL);//附加信息
  159. //3普通按钮
  160. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  161. "登录",//按钮的名字
  162. WS_CHILD | WS_VISIBLE,//风格
  163. 1000, 600,//坐标
  164. 50, 50,//宽高
  165. hWnd, //父窗口句柄
  166. (HMENU)2001,
  167. g_hInstance,
  168. NULL);
  169. //4分组框
  170. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  171. "分组框",//分组框的名字
  172. WS_CHILD | WS_VISIBLE | BS_GROUPBOX,//风格
  173. 1000, 100,//坐标
  174. 500, 500,//宽高
  175. hWnd, //父窗口句柄
  176. (HMENU)2002,
  177. g_hInstance,
  178. NULL);
  179. //单选按钮
  180. //选中哪一个,可以通过消息来区分。
  181. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  182. "A",//按钮的名字
  183. WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP,//风格,通过WS_GROUP来设置单选按钮的分组,即从一个WS_GROUP开始直到遇到下一个WS_GROUP为止,为一组。
  184. 1000, 300,//坐标
  185. 100, 30,//宽高
  186. hWnd, //父窗口句柄
  187. (HMENU)2003,
  188. g_hInstance,
  189. NULL);
  190. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  191. "B",//按钮的名字
  192. WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,//风格
  193. 1000, 330,//坐标
  194. 100, 30,//宽高
  195. hWnd, //父窗口句柄
  196. (HMENU)2004,
  197. g_hInstance,
  198. NULL);
  199. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  200. "C",//按钮的名字
  201. WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP,//风格
  202. 1000, 360,//坐标
  203. 100, 30,//宽高
  204. hWnd, //父窗口句柄
  205. (HMENU)2005,
  206. g_hInstance,
  207. NULL);
  208. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  209. "D",//按钮的名字
  210. WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,//风格
  211. 1000, 390,//坐标
  212. 100, 30,//宽高
  213. hWnd, //父窗口句柄
  214. (HMENU)2006,
  215. g_hInstance,
  216. NULL);
  217. //4复选框
  218. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  219. "D",//按钮的名字
  220. WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,//风格
  221. //CHECKBOX : 手动复选框,鼠标点击没有反应,必须通过代码来设置。
  222. //AUTOCHECKBOX : 自动复选框,鼠标点击方框就可以选中。
  223. //AUTO3STATE : 三态复选框,有黑色选中,灰色选中,没有选中三种状态。
  224. 1000, 410,//坐标
  225. 100, 30,//宽高
  226. hWnd, //父窗口句柄
  227. (HMENU)2007,
  228. g_hInstance,
  229. NULL);
  230. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  231. "D",//按钮的名字
  232. WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,//风格
  233. 1000, 440,//坐标
  234. 100, 30,//宽高
  235. hWnd, //父窗口句柄
  236. (HMENU)2008,
  237. g_hInstance,
  238. NULL);
  239. //5文本编辑框
  240. CreateWindow("Edit",
  241. "光谷小五郎",//文本编辑框中的默认内容
  242. WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL /*允许横向滚动*/ | ES_AUTOVSCROLL/*允许竖向滚动*/ | ES_MULTILINE
  243. /*允许多行(竖向滚动风格必须和允许多行风格结合使用才能生效)*/ //风格
  244. //并且只有配合滚动条才好玩
  245. | WS_HSCROLL/*横向滚动条*/ | WS_VSCROLL,/*竖向滚动条*/
  246. 1000, 500,//坐标
  247. 100, 100,//宽高
  248. hWnd, //父窗口句柄
  249. (HMENU)5001,
  250. g_hInstance,
  251. NULL);
  252. CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
  253. "获取文本框中文字",//按钮的名字
  254. WS_CHILD | WS_VISIBLE,//风格
  255. 1000, 700,//坐标
  256. 300,100,//宽高
  257. hWnd, //父窗口句柄
  258. (HMENU)5002,
  259. g_hInstance,
  260. NULL);
  261. CreateWindow("Edit","光谷小五郎",//文本编辑框中的默认内容
  262. WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL /*允许横向滚动*/ | ES_AUTOVSCROLL/*允许竖向滚动*/ | ES_PASSWORD//密码框
  263. /*允许多行(竖向滚动风格必须和允许多行风格结合使用才能生效)*/ //风格
  264. //并且只有配合滚动条才好玩
  265. | WS_HSCROLL/*横向滚动条*/ | WS_VSCROLL,/*竖向滚动条*/
  266. 1000, 100,//坐标
  267. 100, 100,//宽高
  268. hWnd, //父窗口句柄
  269. (HMENU)5003,
  270. g_hInstance,
  271. NULL);
  272. //6.组合框:下拉列表+文本编辑框
  273. CreateWindow("ComboBox",//类名,不能自己乱输入,必须是系统有的
  274. "简单组合框",//按钮的名字
  275. WS_CHILD | WS_VISIBLE | CBS_SIMPLE,//风格
  276. 700, 100,//坐标
  277. 100, 100,//宽高
  278. hWnd, //父窗口句柄
  279. (HMENU)6001,
  280. g_hInstance,
  281. NULL);
  282. //下拉组合框
  283. HWND simpleCombo = CreateWindow("ComboBox",//类名,不能自己乱输入,必须是系统有的
  284. "下拉组合框",//按钮的名字
  285. WS_CHILD | WS_VISIBLE| CBS_DROPDOWN /*下拉框*/ | WS_VSCROLL/*垂直滚动条*/,//风格
  286. 700, 400,//坐标
  287. 300, 100,//宽高
  288. hWnd, //父窗口句柄
  289. (HMENU)6001,
  290. g_hInstance,
  291. NULL);
  292. //给组合框添加选项
  293. char name[20];
  294. for (int i = 0; i < 7; i++) {
  295. memset(name, 0, 20);
  296. wsprintf(name, "%d娃", i + 1);
  297. SendMessage(simpleCombo, CB_ADDSTRING/*添加选项*/, 19, (LPARAM)name);
  298. }
  299. }
  300. LRESULT CALLBACK WndProc(HWND hWnd,//窗口句柄
  301. //CALLBACK表示是一个回调函数,LRESULT是函数返回值的类型,可以通过查看wc.lpfnWndProc的定义查看
  302. UINT code,//消息 msg.message
  303. WPARAM wParam,//消息附加信息
  304. LPARAM lParam//消息附加信息
  305. ) {
  306. HMENU hGet;
  307. RECT rect;
  308. //用switch case 来判断是什么消息
  309. switch (code) {
  310. case WM_CONTEXTMENU:
  311. GetWindowRect(hWnd, &rect);//获取当前窗口客户区的矩形,传参给rect
  312. TrackPopupMenu(hRight, TPM_RIGHTBUTTON, LOWORD(lParam), HIWORD(lParam), 0, hWnd, &rect);//右键点击时显示菜单
  313. break;
  314. #if 0
  315. case WM_RBUTTONUP://当单击右键并弹起时,会收到此消息
  316. //TrackPopupMenu()
  317. GetWindowRect(hWnd, &rect);//获取当前窗口客户区的矩形,传参给rect
  318. TrackPopupMenu(hRight, TPM_CENTERALIGN, rect.left+LOWORD(lParam),rect.top+HIWORD(lParam), 0, hWnd, &rect);//右键点击时显示菜单
  319. break;//用这种方式右键菜单弹出的位置有点问题,因为WM_RBUTTONUP的lParam中存储的是相对于桌面的xy坐标,需要用当前窗口即rect.left+LOWOR(lParam)转化成相对于窗口的。
  320. #endif
  321. break;
  322. case WM_SYSCOMMAND://点击系统菜单项就会产生WM_SYSCOMMAND消息
  323. switch (wParam) {//不同的系统菜单项会产生不同的WM_SYSCOMMAND消息,这些消息的wParam中保存的菜单项id号不同
  324. case 1112://之前我们自己追加的菜单项id号为1112
  325. MessageBox(hWnd, "123", "系统菜单项", NULL);
  326. break;
  327. default:
  328. break;
  329. }
  330. break;
  331. case WM_KEYUP:
  332. break;
  333. case WM_KEYDOWN:
  334. switch (wParam) {
  335. case VK_UP:
  336. y -= 10;
  337. n = 0;
  338. break;
  339. case VK_DOWN:
  340. y += 10;
  341. n = 1;
  342. break;
  343. case VK_LEFT:
  344. x -= 10;
  345. n = 2;
  346. break;
  347. case VK_RIGHT:
  348. x += 10;
  349. n = 3;
  350. break;
  351. }
  352. break;
  353. case WM_COMMAND://当点击菜单项时会发送WM_COMMAND消息,由于不同的菜单项我们设置了不同的id,所以可以根据菜单项的id来区分
  354. wmId = LOWORD(wParam);//保存按钮和控件的Id
  355. wmEvent = HIWORD(wParam);//保存事件
  356. switch (wmId) {
  357. case 6001: {
  358. CHAR buff[256] = { 0 };
  359. HWND hCombo = GetDlgItem(hWnd, 6001);//得到句柄为hWnd的窗口中id为6001的控件的句柄
  360. if (wmEvent == CBN_SELCHANGE) {
  361. SendMessage(hCombo, WM_GETTEXT, 255, (LPARAM)buff);
  362. MessageBox(NULL, buff, NULL, NULL);
  363. }
  364. break; }
  365. case 5001:
  366. if (wmEvent == EN_CHANGE/*如果文本编辑框的内容有发生改变*/) {
  367. //MessageBox(NULL, "改变", "文本编辑框", NULL);
  368. }
  369. break;
  370. case 5002: {
  371. //获取文本框内容并显示
  372. HWND hEdit = GetDlgItem(hWnd, 5001); // 获取文本框句柄
  373. CHAR buff[256] = { 0 };
  374. RECT rect = { 0 };
  375. SendMessage(hEdit, WM_GETTEXT/*获取文本框内容*/, 255,(LPARAM)buff);//这里的wparam参数是获取的字符数量,lparam则是放到什么地方去
  376. //SendMessage(hEdit, EM_GETRECT, NULL, (LPARAM)&rect);//获取文本框的矩形信息
  377. //wsprintf(buff, "%d,%d,%d,%d", rect.top, rect.left, rect.bottom, rect.right)
  378. MessageBox(NULL, buff, "文本框内容", NULL);
  379. break;
  380. }
  381. case 1001:
  382. if(wmEvent == STN_CLICKED){
  383. //MessageBox(NULL, "蔡徐坤好帅","单击控件",NULL);
  384. HICON hIcon1 = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));
  385. //获取静态位图框的句柄
  386. HWND hStaticWnd=GetDlgItem(hWnd,1002);//获得对话框的句柄,子窗口可以称为对话框,这里1002是静态位图框
  387. //向控件发消息
  388. SendMessage(hStaticWnd,STM_SETICON,(WPARAM)hIcon1,NULL);
  389. }
  390. else if (wmEvent == STN_DBLCLK) {//双击消息会覆盖第二个单击消息,但是第一个单击消息 不会被覆盖
  391. //MessageBox(NULL, "蔡徐坤超级帅", "双击控件", NULL);
  392. //MessageBox(NULL, "蔡徐坤好帅","单击控件",NULL);
  393. HICON hIcon2 = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SMALL));
  394. //获取静态位图框的句柄
  395. HWND hStaticWnd = GetDlgItem(hWnd, 1002);//获得对话框的句柄,子窗口可以称为对话框,这里1002是静态位图框
  396. //向控件发消息
  397. SendMessage(hStaticWnd, STM_SETICON, (WPARAM)hIcon2, NULL);
  398. }
  399. break;
  400. case 2001:
  401. /*即如果登录按钮按下,则A,B两个单选框的id,如果是第2次点击,则设置A被选中,第1次点击,则设置B被选中*/
  402. g_count++;
  403. HWND hA= GetDlgItem(hWnd, 2003);
  404. HWND hB = GetDlgItem(hWnd, 2004);
  405. HWND hC = GetDlgItem(hWnd, 2005);
  406. LRESULT ret = SendMessage(hC, BM_GETCHECK, BST_CHECKED, NULL);//返回C是否被选中
  407. //if (g_count % 2 == 0)
  408. if (ret==BST_UNCHECKED){//如果C没有被选中,则选中A
  409. SendMessage(hB, BM_SETCHECK, BST_UNCHECKED, NULL);
  410. SendMessage(hA, BM_SETCHECK, BST_CHECKED, NULL);
  411. }
  412. else {
  413. SendMessage(hA, BM_SETCHECK, BST_UNCHECKED, NULL);//取消A被选中
  414. SendMessage(hB, BM_SETCHECK, BST_CHECKED, NULL);//设置B被选中
  415. }
  416. break;
  417. }
  418. switch (wParam) {// 点击不同的菜单项,WM_COMMAND的附加消息wParam中存储的id号不同
  419. case 2522:
  420. MessageBox(hWnd, "切换角色为蔡徐坤", "恭喜", MB_OK);
  421. name0 = "cxk0.bmp";
  422. name1 = "cxk1.bmp";
  423. name2 = "cxk2.bmp";
  424. name3 = "cxk3.bmp";
  425. break;
  426. //点击 桃乃木香奈 2524 菜单项 设置 波多野结衣菜单项 2521 可选中(由灰色变成黑色)
  427. //点击 波多野结衣 2521 菜单项 设置 桃谷绘里香 2523 菜单项选中
  428. case 2524:
  429. hGet =GetSubMenu(GetMenu(hWnd),1);//GetMenu拿到的是窗口句柄为hWnd的窗口的顶层菜单的菜单句柄;以之作为参数去拿顶层菜单的弹出式菜单
  430. EnableMenuItem(hGet, 2521, MF_ENABLED);//设置波多野结衣菜单项为黑色
  431. break;
  432. case 2521:
  433. hGet = GetSubMenu(GetMenu(hWnd), 1);
  434. //通过id号来选中桃谷绘里香菜单项
  435. //CheckMenuItem(hGet, 2523, MF_CHECKED);//设置桃谷绘里香被选中
  436. //通过相对位置来选中桃谷绘里香 菜单项
  437. CheckMenuItem(hGet, 3, MF_CHECKED | MF_BYPOSITION);
  438. break;
  439. case 2525:
  440. hGet = GetSubMenu(GetMenu(hWnd), 1);
  441. switch (flag) {
  442. case 0:
  443. CheckMenuItem(hGet, 2522, MF_CHECKED);
  444. flag = 1;
  445. break;
  446. case 1:
  447. CheckMenuItem(hGet, 2522, MF_UNCHECKED);
  448. flag = 0;
  449. break;
  450. }
  451. break;
  452. }
  453. break;
  454. case WM_MOUSEMOVE:
  455. break;
  456. case WM_CREATE://代表窗口创建消息
  457. OnCreate1(hWnd);
  458. OnCreate(hWnd, wParam, lParam);
  459. //帧:一秒钟切换图片数。
  460. //人眼可以识别的流畅动画,一秒钟16张图片以上。
  461. SetTimer(hWnd, 6666, 50, NULL);//定时器id6666,间隔50毫秒,
  462. break;
  463. case WM_TIMER:
  464. tietu(hWnd);//因为每隔50毫秒,发送一次定时器消息,所以每隔50毫秒切一次图
  465. break;
  466. case WM_PAINT://绘图消息
  467. {
  468. PAINTSTRUCT ps;
  469. HDC hdc = BeginPaint(hWnd, &ps);//拿到设备DC,返回值为DC设备句柄
  470. #if 0
  471. //1.创建画笔
  472. HPEN hPen0=CreatePen(PS_DASH, 10, RGB(255, 20, 20));//返回画笔对象的句柄
  473. HPEN hPen1 = CreatePen(PS_SOLID, 3, RGB(10, 10, 30));
  474. //2.设置画笔:即拿这支笔
  475. HGDIOBJ hOldpen=SelectObject(hdc, hPen0);
  476. /*
  477. HGDIOBJ 是一个类,是windows上所有GDI类型的基类,基类指针可以指向派生类的对象。HGDIOBJ x=HPEN hpen没有问题
  478. */
  479. //3.画图
  480. MoveToEx(hdc, 30, 30, NULL);//画线,设置起始点
  481. LineTo(hdc, 600, 30);//lineto函数划线,只会设置划线的终点。
  482. //4.还原画笔
  483. SelectObject(hdc,hOldpen);
  484. //5删除画笔
  485. DeleteObject(hPen0);
  486. DeleteObject(hPen1);
  487. #endif
  488. /*
  489. //1创建画刷
  490. HBRUSH hBrush1=CreateSolidBrush(RGB(255, 0, 0));
  491. HBRUSH hBrush2 = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));//第一个参数为画刷的风格
  492. //2设置画刷到DC中
  493. HGDIOBJ hOldBrush = SelectObject(hdc, hBrush1);
  494. //3使用画刷
  495. RoundRect(hdc, 30, 30, 100, 100, 100, 100);//画椭圆矩形
  496. SelectObject(hdc, hBrush2);
  497. Rectangle(hdc, 150, 150, 300, 300);
  498. //4还原画刷
  499. SelectObject(hdc, hBrush2);
  500. //5删除画刷
  501. DeleteObject(hBrush2);
  502. EndPaint(hWnd, &ps);
  503. */
  504. #if 0
  505. //截屏:拿到操作系统当前屏幕某个区域内的图像
  506. HDC hScreenDc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);//第一个参数为设备,TEXT(“DISPLAY”)表示输出设备
  507. for (int y = 0; y < 300; y++) {
  508. for (int x = 0; x < 300; x++) {
  509. BitBlt(hdc, 0, 0, 300, 300,hScreenDc,0,0,SRCCOPY);//把hScreenDc中的内容画到hdc里面,从(0,0)画到(300,300),从hScreenDc的(0,0)开始去拿。画的方式SRCCOPY直接拷贝。
  510. }
  511. }
  512. #endif
  513. //贴图
  514. //1.有图片
  515. //HBITMAP hBitmap1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1));//加载位图,只能加载bmp类型的图片
  516. HANDLE hBitmap1 = LoadImage(g_hInstance, "bk.bmp", IMAGE_BITMAP, 641, 480, LR_LOADFROMFILE);
  517. //2.创建兼容DC
  518. HDC hBuffDc = CreateCompatibleDC(hdc);
  519. //3.图片放入兼容DC//将图片里面的东西,放到内存中
  520. SelectObject(hBuffDc, hBitmap1);
  521. //参数:当前程序实例句柄,资源id
  522. //loadImage()之前已经讲过了
  523. //4.贴图:将内存中的东西放到窗口中
  524. BitBlt(hdc, 0, 0,641,480,hBuffDc,0,0,SRCPAINT);
  525. //贴到哪里 贴到窗口的哪个坐标(x,y) 贴图的宽高 从哪里获取图片,从获取图片的哪个坐标开始截图 贴图方式 SRCAND透明贴图
  526. break;
  527. }
  528. case WM_DESTROY:
  529. PostQuitMessage(0);//PostQuitMessage函数发送一个WM_QUIT消息到线程消息队列并且立即返回
  530. break;
  531. default:
  532. return DefWindowProc(hWnd, code, wParam, lParam);//意味着开始下一次消息循环
  533. }
  534. return DefWindowProc(hWnd, code, wParam, lParam);//意味着开始下一次消息循环
  535. }
  536. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hParentInstance, LPSTR lpCmd, int len) {
  537. g_hInstance = hInstance;
  538. //1.写主函数
  539. //2.在主函数中注册窗口类 WNDCLASS WNDCLASSEX(64位扩展的)
  540. WNDCLASSEX wc;//wc是一个窗口类 类型的 结构体,它里面有很多成员变量,一个一个给它们初始化就可以了
  541. wc.cbSize = sizeof(WNDCLASSEX);//窗口类大小
  542. wc.cbClsExtra = NULL;//窗口类附加信息 即 对窗口类的说明 等于NULL表示没有附加信息
  543. wc.cbWndExtra = NULL;//窗口附加信息 即对窗口的说明
  544. wc.lpszClassName = "蔡徐坤大战av女优";//窗口类名,主要是为了标志版权 用spy++工具可以查看类名
  545. //wc.hbrBackground=NULL;//背景 设置背景颜色
  546. wc.hbrBackground = (HBRUSH)GetStockObject(3);//百度查,记不住
  547. wc.hCursor = NULL;
  548. //wc.hIcon = NULL;//窗口的图标(任务栏) 用loadicon函数来加载图标:加载一个图标资源,并且返回这个图标资源的句柄。
  549. wc.hIcon = NULL;
  550. //两种方式loadIcon和(HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,32,32,LR_LOADTANSPARENT);
  551. //加载方式:LR_LOADTANSPARENT资源方式加载,文件方式加载LOADFROMFILE
  552. wc.hIconSm = NULL;//小图标
  553. wc.hInstance = hInstance;//当前应用程序的实例句柄
  554. wc.lpfnWndProc = WndProc; //消息处理函数=你自己定义的消息处理函数的名字
  555. wc.lpszMenuName = NULL; //菜单
  556. wc.style = CS_HREDRAW | CS_VREDRAW;//窗口风格=水平/垂直滚动条
  557. RegisterClassEx(&wc); //正式注册窗口类,只要把结构体wc的地址传入即可。
  558. //3.创建窗口 CreateWindow //HWND 窗口句柄类型 Handle Window
  559. HWND hWnd = CreateWindowEx( //因为创建窗口函数会返回创建的窗口的句柄,所以首先定义好窗口句柄类型的变量。
  560. NULL,//窗口的附加风格
  561. wc.lpszClassName, //窗口类名
  562. "蔡徐坤大战av女优",//窗口名
  563. WS_OVERLAPPEDWINDOW,//窗口的风格
  564. 1000, 100,//窗口出现的位置 (x,y)
  565. 600, 600,//窗口的宽高
  566. NULL,//父窗口实例句柄
  567. NULL,//窗口的菜单的句柄
  568. hInstance,//窗口的实例句柄(当前应用程序实例句柄
  569. NULL);//附加信息 消息是个结构体,消息有两个附加信息:lParam wParam
  570. /*如果创建窗口失败,则CreateWindow的返回值为NULL即0;
  571. *如果创建窗口成功,则CreateWindow的返回值为所创建窗口的句柄
  572. */
  573. /*
  574. if(NULL==hWnd){
  575. MessageBox(NULL,"创建窗口失败","警告",MB_OK);
  576. return -1;
  577. }
  578. else{
  579. MessageBox(NULL,"创建窗口成功","恭喜",MB_OK);
  580. }
  581. */
  582. //4.显示刷新窗口 ShowWindow updateWindow
  583. ShowWindow(hWnd, 5);//传入窗口的句柄即可。
  584. UpdateWindow(hWnd); //传入窗口的句柄即可。
  585. AllocConsole();//得到命令行窗口使用权限
  586. g_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//用函数得到命令行窗口句柄,赋值给全局变量g_hConsole
  587. //5.定义窗口的消息处理函数
  588. //消息循环是一个死循环,永远不会结束,除非。。。你写一个语句break
  589. while (1) {
  590. //获取消息
  591. //GetMessage(&msg, NULL, NULL, NULL);//GetMessage函数是一个阻塞函数,如果接收一个消息所用的时间过长,在此期间内,如果有另一个消息被发送,就会接受不到这个消息
  592. if (PeekMessage(&msg, NULL, NULL, NULL, NULL))//最后一个参数表示是否删除消息
  593. /*PeekMessage的工作原理:非阻塞方式接受消息,主要查看是否有消息,不会将消息存入MSG结构体中,GetMessage函数负责将消息存入MSG结构体中。
  594. Peekmessage会检查消息队列,如果消息队列中有消息,函数就会查看最后一个参数,
  595. 如果最后一个参数为false或者NULL,直接返回1
  596. 如果最后一个参数为true,从消息队列中删除消息,然后返回1
  597. 如果消息队列中没有消息,直接返回0
  598. */ {
  599. if (0 == GetMessage(&msg, NULL, NULL, NULL)) break;
  600. /*GetMessage工作原理:
  601. GetMessage从消息队列中获取一个消息存放到MSG结构体中。
  602. 如果消息队列中有消息,把消息存入MSG,删除当前程序消息队列中的消息,返回非0
  603. 直到遇到WM_QUIT消息才返回0.注意:关闭窗口不会发送WM_QUIT消息,只会发送WM_DESTROY消息,只有在消息处理函数中定义当收到WM_DESTROY时,向消息队列中添加WM_QUIT消息,
  604. 才能通过if(0 == GetMessage(&msg, NULL, NULL, NULL)) break;退出循环。
  605. 如果当前程序消息队列中没有消息,就去系统消息队列中看有没有消息。如果系统消息队列
  606. 里面有消息,就把系统消息队列中的消息放入当前程序消息队列。如果系统消息队列中没有消息,就
  607. 检查窗口是否需要重新绘制。如果需要重新绘制,操作系统发送WM_PAINT消息,如果不需要重新绘制
  608. 查看是否有定时器,如果有定时器,处理定时器消息,如果没有定时器,优化资源,处理内存,继续等待。
  609. 消息循环处理消息的次数可能小于消息处理函数处理消息的次数,因为其他应用程序的消息也可能发送给消息处理函数处理。
  610. */
  611. /*
  612. if (msg.message == WM_QUIT) { //WM_QUITE消息表示整个窗口退出
  613. break;
  614. }
  615. */
  616. //翻译消息
  617. TranslateMessage(&msg);//翻译消息
  618. /*消息的翻译主要针对键盘消息,键盘消息只有两个:
  619. WM_TDOWN
  620. WM_TUP
  621. if(msg.message==WM_KEY 按键消息){
  622. if(是否可见字符){//可见字符即代表字符有回显,例如F1F2..PgUp等不是可见字符。
  623. //如果是可见字符,代表应该告诉应用程序,用户按键是用来编辑,发送的是一个字符,否则,就认为用户按键是发送一个指令。
  624. //如果用户发送的是一个字符,就需要翻译一下
  625. if(Caps Lock是否按下){
  626. PostMessage(大写字母消息);//发送大写字母消息
  627. }else{
  628. PostMessage(小写字母消息);//发送小写字母消息
  629. }
  630. }
  631. }
  632. return;
  633. */
  634. DispatchMessage(&msg);//派发消息,群发消息,给当前所有的应用程序都发送。而PostMessage表示只对当前应用程序的消息处理函数发送消息。
  635. }
  636. }
  637. //6.消息循环 循环 接受消息 翻译消息 派发消息
  638. //点击动作 操作系统产生消息 发给窗口应用程序,应用程序里面的“消息循环”接收消息,调用对应的消息处理函数,产生对应的响应动作。
  639. return 0;
  640. }
  1. #include <windows.h>
  2. #include <cstdio>
  3. #include <iostream>
  4. using namespace std;
  5. HINSTANCE g_hInstance;
  6. template <typename T>
  7. void MyPrintf(char* str,T data1,T data2){
  8. AllocConsole();
  9. HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  10. //HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
  11. //HANDLE hError = GetStdHandle(STD_ERROR_HANDLE);
  12. char buff[1024]={0};
  13. sprintf(buff,str,data1,data2);
  14. WriteConsole(hOutput,buff,strlen(buff),NULL,NULL);
  15. return;
  16. }
  17. template <typename T>
  18. void MyPrintf(char* str,T data){
  19. AllocConsole();
  20. HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  21. //HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
  22. //HANDLE hError = GetStdHandle(STD_ERROR_HANDLE);
  23. char buff[1024]={0};
  24. sprintf(buff,str,data);
  25. WriteConsole(hOutput,buff,strlen(buff),NULL,NULL);
  26. return;
  27. }
  28. #if 1
  29. struct task{
  30. char* content;
  31. int importance;
  32. task(){
  33. memset(this,0,sizeof(task));
  34. }
  35. task(char* str,int _importance);
  36. };
  37. task::task(char* str,int _importance){
  38. int len = strlen(str);
  39. content = (char*)malloc(sizeof(char)*(len+1));
  40. if(content == NULL){
  41. MyPrintf("%s\n","开内存失败!");
  42. return;
  43. }
  44. memset(content,0,sizeof(char)*(len+1));
  45. strcpy(content,str);
  46. importance = _importance;
  47. }
  48. class taskQueue{
  49. task* pBuff;
  50. int len;
  51. int capacity;
  52. public:
  53. taskQueue(){memset(this,0,sizeof(taskQueue)};
  54. bool insertTask(task t);
  55. void displayTask();
  56. bool popTask();
  57. void sortTaskByImportance();
  58. }
  59. bool taskQueue::insertTask(task t){
  60. len++;
  61. if(len >= capacity){
  62. capacity += (capacity == 0)?1:capacity>>1;
  63. task* pNew = (task*)malloc(sizeof(task)*capacity);
  64. if(pNew == NULL){
  65. return false;
  66. }
  67. memset(pNew,0,sizeof(task)*capacity);
  68. memcpy(pNew,pBuff,sizeof(task)*(len-1));
  69. free(pBuff);
  70. pBuff = pNew;
  71. }
  72. pBuff[len-1] = t;
  73. return true;
  74. }
  75. void taskQueue::displayTask(){
  76. for(int i=0;i<len;i++){
  77. MyPrintf("第%d个任务-",i);
  78. MyPrintf("content:%s-importance:%d\n",pBuff[i].content,pBuff[i].importance);
  79. }
  80. return;
  81. }
  82. #endif
  83. void OnCreate(HWND hwnd){
  84. CreateWindow("Static","任务队列:\n高数\nC语言\n电路基础\n",WS_VISIBLE|WS_CHILD|SS_CENTER,40,20,260,320,hwnd,(HMENU)1000,g_hInstance,NULL);
  85. CreateWindow("Edit","请输入要添加待办事项...",WS_CHILD|WS_VISIBLE|SS_CENTER,40,350,220,30,hwnd,(HMENU)1001,g_hInstance,NULL);
  86. CreateWindow("Edit","请输入该事项的重要程度(用整数表示)",WS_CHILD|WS_VISIBLE|SS_CENTER,40,385,220,30,hwnd,(HMENU)1003,g_hInstance,NULL);
  87. CreateWindow("Button","添加",WS_CHILD|WS_VISIBLE,265,350,35,30,hwnd,(HMENU)1002,g_hInstance,NULL);
  88. return;
  89. }
  90. void displayCursorPos(LPARAM lParam){
  91. POINT pos;
  92. pos.y = HIWORD(lParam);
  93. pos.x = LOWORD(lParam);
  94. MyPrintf("光标的客户区坐标 {x:%d,y:%d}\n",pos.x,pos.y);
  95. return;
  96. }
  97. void OnCommand(HWND hwnd,WPARAM wParam){
  98. int wmId = LOWORD(wParam);
  99. int wmEvent = HIWORD(wParam);
  100. switch(wmId){
  101. case 1002://添加按钮
  102. HWND hEdit = GetDlgItem(hwnd,1001);
  103. char buff[1024] = {0};
  104. SendMessage(hEdit,WM_GETTEXT,255,(LPARAM)buff);
  105. //MyPrintf("文本编辑框中的内容为:%s\n",buff);
  106. task(buff,)
  107. }
  108. return;
  109. }
  110. /* This is where all the input to the window goes to */
  111. LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
  112. switch(Message) {
  113. case WM_CREATE:
  114. OnCreate(hwnd);
  115. break;
  116. /* trap the WM_CLOSE (clicking X) message, and actually tell the window to close */
  117. case WM_CLOSE: {
  118. DestroyWindow(hwnd);
  119. break;
  120. }
  121. /* Upon destruction, tell the main thread to stop */
  122. case WM_DESTROY: {
  123. PostQuitMessage(0);
  124. break;
  125. }
  126. case WM_MOUSEMOVE:
  127. displayCursorPos(lParam);
  128. break;
  129. case WM_COMMAND:
  130. OnCommand(hwnd,wParam);
  131. break;
  132. /* All other messages (a lot of them) are processed using default procedures */
  133. default:
  134. return DefWindowProc(hwnd, Message, wParam, lParam);
  135. }
  136. return 0;
  137. }
  138. /* The 'main' function of Win32 GUI programs: this is where execution starts */
  139. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  140. g_hInstance = hInstance;
  141. WNDCLASSEX wc; /* A properties struct of our window */
  142. HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
  143. MSG Msg; /* A temporary location for all messages */
  144. /* zero out the struct and set the stuff we want to modify */
  145. memset(&wc,0,sizeof(wc));
  146. wc.cbSize = sizeof(WNDCLASSEX);
  147. wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
  148. wc.hInstance = hInstance;
  149. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  150. /* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
  151. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  152. wc.lpszClassName = "WindowClass";
  153. wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
  154. wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  155. if(!RegisterClassEx(&wc)) {
  156. MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
  157. return 0;
  158. }
  159. hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
  160. CW_USEDEFAULT, /* x */
  161. CW_USEDEFAULT, /* y */
  162. 640, /* width */
  163. 480, /* height */
  164. NULL,NULL,hInstance,NULL);
  165. if(hwnd == NULL) {
  166. MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
  167. return 0;
  168. }
  169. /*
  170. This is the heart of our program where all input is processed and
  171. sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
  172. this loop will not produre unreasonably CPU usage
  173. */
  174. while(GetMessage(&Msg, NULL, 0, 0) > 0) { /* If no error is received... */
  175. TranslateMessage(&Msg); /* Translate keycodes to chars if present */
  176. DispatchMessage(&Msg); /* Send it to WndProc */
  177. }
  178. return Msg.wParam;
  179. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/71547
推荐阅读
相关标签
  

闽ICP备14008679号