win32Day06:控件

2023-05-16

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创建字体
          HFONT CreateFont(
              int cHeight, //字体的逻辑高度
              int cWidth, //字体的逻辑宽度
              int cEscapement, //指定移位向量相对X轴的偏转角度
              int cOrientation, //指定字符基线相对X轴的偏转角度
              int cWeight, //设置字体粗细程度
              DWORD bItalic, //是否启用斜体
              DWORD bUnderline, //是否启用下划线
              DWORD bStrikeOut, //是否启用删除线
              DWORD iCharSet, //指定字符集
              DWORD iOutPrecision, //输出精度
              DWORD iClipPrecision, //剪裁精度
              DWORD iQuality, //输出质量
              DWORD iPitchAndFamily, //字体族
              LPCSTR pszFaceName //字体名);

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

        5. 静态文本框举例:

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

           

    2. 静态位图框:
      1. 添加资源 Bitmap 其实建议导入为ICON类型的资源。这样之后做图标变换方便点。
      2. 修改位图资源,并得到这些资源的ID
      3. CreateWindow(
            "Static",
            "#130",//位图ID
            WS_CHILD|WS_VISIBLE|SS_BITMAP,
            30,30,
            150,30,//虽然位图资源有自己宽高,但是这里我们可以修改它的宽高
            hwnd,
            (HMENU)1002,
            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),这样就知道触发了谁的什么事件了。

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

      5. case WM_COMMAND:{
            int wmId = LOWORD(wParam);
            int wmEvent = HIWORD(wParam);
            switch(wmId){
                case 1001:
                    if(wmEvent == STN_CLICKED){//如果是单击事件
                        //1.加载新图标到窗口实例程序中
                        HICON hIcon1 = LoadIcon(hInst,MAKEINTERSOURCE(IDI_ICON1));
                        HWND hStaticWnd = GetDlgItem(hwnd,1002);
                        //3.向控件发送消息来操作控件
                        SendMessage(hStaticWnd,STM_SETICON,(WPARAM)hIcon1,NULL);
                        /*表示给hStaticWnd发送信息
                        消息内容为:STM_SETICON设置icon
                        附加消息为:hIcon1表示设置为这个icon
                        */
                    }else if(wmEvent == STN_DBLCLK){
                         //1.加载新图标到窗口实例程序中
                        HICON hIcon1 = LoadIcon(hInst,MAKEINTERSOURCE(IDI_ICON2));
                        HWND hStaticWnd = GetDlgItem(hwnd,1002);
                        //3.向控件发送消息来操作控件
                        SendMessage(hStaticWnd,STM_SETICON,(WPARAM)hIcon2,NULL);
                        /*表示给hStaticWnd发送信息
                        消息内容为:STM_SETICON设置icon
                        附加消息为:hIcon1表示设置为这个icon
                        */
        
                    }
        
            }
        
        }
        

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

      6. 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.。
       CreateWindow("Button","选项1",WS_CHILD|WS_VISIBLE|SS_CENTER|BS_RADIOBUTTON,
      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设置一组的第一个。

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

           

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

         CreateWindow("Button","分组框",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
        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. 例如:

           case WM_COMMAND:
                  {
                      int wmId = LOWORD(wParam);
          	    int wmEvent = HIWORD(wParam);
                      // 分析菜单选择:
                      switch (wmId)
                      {
          			case 2001: {
          				HWND hC = GetDlgItem(hWnd, 2003);
          				SendMessage(hC, BM_SETCHECK, BST_CHECKED, NULL);
          
          				break;
          			}
                      }
                  }

           

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

       

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

      dsa

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

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

    其中WS_VSCROLL表示加滚动条。

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

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

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

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

    case 6001:
        if(wmEvent == CBN_SELENDOK){
            MessageBox(hwnd,"选择框的选择发生了变化!",NULL,NULL);
        }else if(wmEvent == CBN_EDITCHANGE){
            MessageBox(hwnd,"选择框的内容编辑发生了变化!",NULL,NULL);
        }
        break;

     

  7. 下拉框 :只可以通过下拉来选择内容。
  8. 滚动条
  9. 作业:做一个类型于QQ的登录界面。
#include <windows.h>
#include "stdafx.h"
#include "Resource.h"
#include <stdio.h>
#include <cstdio>
#include <string.h>
#include <cstring>
#include <iostream>
using namespace std;

HINSTANCE g_hInstance;
HCURSOR g_hCursor1, g_hCursor2;//光标句柄
MSG msg;//声明一个MSG类型的消息结构体
HANDLE g_hConsole;//定义一个HANDLE类型的全局变量,之后要将命令行窗口句柄赋值给它,命名时养成习惯:如果是全局变量以g_开头命名它。
HMENU hRight;
int flag = 0;
int i = 0;
HDC hBuffDc;
HDC hMemoryDc;
HDC hDc;
HANDLE hBitmap[5];
HANDLE hBitmap1;
int x = 100;
int y = 100;
int n = 1;
int g_count = 0;

string name0 = "move0.bmp";
string name1 = "move1.bmp";
string name2 = "move2.bmp";
string name3 = "move3.bmp";
int wmId;
int wmEvent;

void zhubei() {
	//1把背景图放入hBuffDc中
	SelectObject(hBuffDc, hBitmap1);
	//2把背景图画入memory中
	BitBlt(hMemoryDc, 0, 0, 641, 480, hBuffDc, 0, 0, SRCCOPY);
	//3把人物图画入memory中
	 //3.1人物图选入hBuffDc中
	SelectObject(hBuffDc, hBitmap[n]);
	//3.2人物图画入memory中
	BitBlt(hMemoryDc, x, y, 60, 108, hBuffDc, 60 * i, 108, SRCAND);
	BitBlt(hMemoryDc, x, y, 60, 108, hBuffDc, 60 * i, 0, SRCPAINT);
	i++;
	//4 把memory当图片画入hDc中
	BitBlt(hDc, 0, 0, 641, 480, hMemoryDc, 0, 0, SRCCOPY);

}
void tietu(HWND hWnd) {
	if (i >= 8) i = 0;
    hDc = GetDC(hWnd);
	//两个兼容DC
	hMemoryDc = CreateCompatibleDC(hDc);//用来放人物
	hBuffDc = CreateCompatibleDC(hDc);//用来放背景
	/*三级缓冲
	先把背景选到hBuffDc中,再把hBuffDc和人物贴到hMemoryDc中,然后把hMemoryDc贴到hDc(屏幕)中
	
	*/
	//创建兼容位图
	HBITMAP hCompatibleBitmap=CreateCompatibleBitmap(hDc, GetSystemMetrics(SM_CXFULLSCREEN), GetSystemMetrics(SM_CYFULLSCREEN));//创建到hDC中,宽高为窗口的宽,窗口的高
	//设置兼容位图到memoryDc
	SelectObject(hMemoryDc, hCompatibleBitmap);
	hBitmap[0] = LoadImage(g_hInstance,name0.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
	hBitmap[1] = LoadImage(g_hInstance,name1.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
	hBitmap[2] = LoadImage(g_hInstance,name2.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);
	hBitmap[3] = LoadImage(g_hInstance,name3.c_str(), IMAGE_BITMAP, 480, 216, LR_LOADFROMFILE);


	hBitmap1 = LoadImage(g_hInstance, "bk.bmp", IMAGE_BITMAP, 641, 480, LR_LOADFROMFILE);

	zhubei();
	/*
	SelectObject(hMemoryDc, hBitmap);
	//贴到哪里 坐标(x,y) 宽高  从哪里贴,从哪的坐标 贴图方式    
	BitBlt(hDc, 80, 108,30,108,hMemoryDc,60*i,108, SRCAND);//将下方的黑色图片按位与去贴。那么黑色遇到任何颜色保持黑色。白色遇到任何颜色仍旧是任何颜色
	BitBlt(hDc, 80, 108, 30, 108, hMemoryDc, 60 * i, 0, SRCPAINT);//将上方的彩色图像按位或去贴。
	i++;
	*/
	/*
	  透明贴图先用SRCAND的方式去贴,然后用SRCPAINT的方式去贴
	  SRCAND 按位与方式,任何东西与上0(黑色)是0(黑色),任何东西与上1(白色)是任何东西自身(不变)。
	  SRCPAINT 按位或方式去贴,彩色 或 黑色= 彩色 黑色 或 任何东西 =任何东西。
	
	
	
	*/
}
//写一个windows窗口 
//5定义消息处理函数 
void OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam) {
#if 0
	//一 系统菜单
	HMENU hSystemMenu=GetSystemMenu(hWnd, 0);//获取系统菜单句柄
	//删除系统菜单项:系统菜单有七项,其中分隔符也算菜单项
	for (int i = 0; i < 6; i++) {
		DeleteMenu(hSystemMenu, 0, MF_BYPOSITION);//按照索引的方式删除,0表示当前状况的第一个,是变化的
		//DeleteMenu(hSystemMenu, 0, MF_BYCOMMAND);//按照下标的方式删除,0表示初期情况下菜单栏的第一个(即分隔符),是固定的。

	}
	//追加系统菜单项:追加就一定在最后追加
	AppendMenu(hSystemMenu, MF_SEPARATOR, 1111, NULL);//第二个参数决定菜单项的样式:分隔符(MF_SEPARATOR)还是字符串,如果第二个参数选分隔符,那么第三个参数就是分隔符的id
	AppendMenu(hSystemMenu, MFT_STRING, 1112, L"(ง •_•)ง(M)");//第二个参数如果是字符串,则最后一个参数为字符串的内容。
	//这里只能决定菜单的样子,而真正地处理才是关键。
	/*真正的处理在消息处理函数中,系统菜单的消息由WM_COMANND消息管理*/
#endif
	//二、顶层菜单
	HMENU hTopMenu = CreateMenu();//创建顶层菜单,返回顶层菜单的句柄
	//创建弹出式菜单
	HMENU hChinese = CreatePopupMenu();
	HMENU hJapan = CreatePopupMenu();
	HMENU hAmerican = CreatePopupMenu();
	HMENU hSearch = CreatePopupMenu();
	//将弹出式菜单添加到顶层菜单中
	AppendMenu(hTopMenu,MF_POPUP,(UINT)hChinese,"国产");//第三个参数需要弹出式菜单的id,我们将句柄强制转化成id类型
	AppendMenu(hTopMenu, MF_POPUP, (UINT)hJapan,"日本");
	AppendMenu(hTopMenu, MF_POPUP, (UINT)hAmerican,"欧美");
	AppendMenu(hJapan, MF_POPUP, (UINT)hSearch,"搜索");
	//添加菜单项到弹出式菜单中
	//添加到国产中
	AppendMenu(hChinese, MF_STRING,2511, "土肥圆矮穷挫");//第三个参数为你设置的这个菜单项的id
	AppendMenu(hChinese, MF_STRING, 2512, "艾栗栗");
	AppendMenu(hChinese, MF_STRING, 2513, "萌琪琪");
	AppendMenu(hChinese, MF_STRING, 2514, "张柏芝艳照门");
	//添加到日本中
	AppendMenu(hJapan, MF_STRING, 2521, "波多野结衣");//第三个参数为你设置的这个菜单项的id
	AppendMenu(hJapan, MF_STRING, 2522, "切换为蔡徐坤");
	AppendMenu(hJapan, MF_STRING, 2523, "桃谷绘里香");
	AppendMenu(hJapan, MF_STRING, 2524, "桃乃木香奈");
	AppendMenu(hJapan, MF_STRING, 2524, "其他");
	AppendMenu(hJapan, MF_STRING, 2525, "选中蔡徐坤");

	//添加到欧美中
	AppendMenu(hAmerican, MF_STRING, 2531, "安洁莉卡");
	//添加菜单项到搜索中
	AppendMenu(hSearch, MF_STRING, 2541, "搜索番号");
	AppendMenu(hSearch, MF_STRING, 2541, "搜索女优");
	AppendMenu(hSearch, MF_STRING, 2541, "搜索男优");
	//显示顶层菜单
	SetMenu(hWnd, hTopMenu);
	//获取菜单项句柄,现在只有我自己设置的菜单项的id
	HMENU hTemp = GetSubMenu(hJapan, 0);//得到波多野结衣菜单项的句柄
    //设置菜单项
	EnableMenuItem(hJapan, 2521,MF_GRAYED);//第一个参数为菜单项所在弹出式菜单的句柄,第二参数该菜单项的id,设置菜单项“波多野结衣”为灰色
	//三、创建右键菜单
	hRight = CreatePopupMenu();
	AppendMenu(hRight, MF_STRING, 3001, "打开男人团");
	AppendMenu(hRight, MF_STRING, 3002, "打开福利档");
	AppendMenu(hRight, MF_STRING, 3003, "打开torrentkitty");



}
//创建控件
void OnCreate1(HWND hWnd) {
	//1静态文本框
	CreateWindow("Static", "鸡你太美",
		WS_CHILD | WS_VISIBLE | SS_CENTER/*左右居中*/ | SS_NOTIFY/*可以被操作*/,//用位运算(按位或)把各个风格组合起来。每个风格宏常量都是一个整数
		700, 700,//坐标
		150, 30,//宽高
		hWnd,//父窗口句柄
		(HMENU)1001,//自定义该窗口控件的ID
		g_hInstance,//窗口应用程序实例句柄
		NULL);//附加信息
   //2静态位图框
	CreateWindow("Static", "#108",//define IDI_SMALL 108
		WS_CHILD | WS_VISIBLE | SS_ICON,//用位运算(按位或)把各个风格组合起来。每个风格宏常量都是一个整数
		1000, 700,//坐标
		30, 30,//宽高
		hWnd,//父窗口句柄
		(HMENU)1002,//自定义该窗口控件的ID
		g_hInstance,//窗口应用程序实例句柄
		NULL);//附加信息
	//3普通按钮

	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"登录",//按钮的名字
		WS_CHILD | WS_VISIBLE,//风格
		1000, 600,//坐标
		50, 50,//宽高
		hWnd, //父窗口句柄
		(HMENU)2001,
		g_hInstance,
		NULL);
	//4分组框
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"分组框",//分组框的名字
		WS_CHILD | WS_VISIBLE | BS_GROUPBOX,//风格
		1000, 100,//坐标
		500, 500,//宽高
		hWnd, //父窗口句柄
		(HMENU)2002,
		g_hInstance,
		NULL);
	//单选按钮
	//选中哪一个,可以通过消息来区分。
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"A",//按钮的名字
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP,//风格,通过WS_GROUP来设置单选按钮的分组,即从一个WS_GROUP开始直到遇到下一个WS_GROUP为止,为一组。
		1000, 300,//坐标
		100, 30,//宽高
		hWnd, //父窗口句柄
		(HMENU)2003,
		g_hInstance,
		NULL);
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"B",//按钮的名字
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,//风格
		1000, 330,//坐标
		100, 30,//宽高
		hWnd, //父窗口句柄
		(HMENU)2004,
		g_hInstance,
		NULL);
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"C",//按钮的名字
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP,//风格
		1000, 360,//坐标
		100, 30,//宽高
		hWnd, //父窗口句柄
		(HMENU)2005,
		g_hInstance,
		NULL);
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"D",//按钮的名字
		WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON,//风格
		1000, 390,//坐标
		100, 30,//宽高
		hWnd, //父窗口句柄
		(HMENU)2006,
		g_hInstance,
		NULL);
	//4复选框
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"D",//按钮的名字
		WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,//风格
		//CHECKBOX : 手动复选框,鼠标点击没有反应,必须通过代码来设置。
		//AUTOCHECKBOX : 自动复选框,鼠标点击方框就可以选中。
		//AUTO3STATE : 三态复选框,有黑色选中,灰色选中,没有选中三种状态。
		1000, 410,//坐标
		100, 30,//宽高
		hWnd, //父窗口句柄
		(HMENU)2007,
		g_hInstance,
		NULL);
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"D",//按钮的名字
		WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,//风格
		1000, 440,//坐标
		100, 30,//宽高
		hWnd, //父窗口句柄
		(HMENU)2008,
		g_hInstance,
		NULL);
	//5文本编辑框
	CreateWindow("Edit",
		"光谷小五郎",//文本编辑框中的默认内容
		WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL /*允许横向滚动*/ | ES_AUTOVSCROLL/*允许竖向滚动*/ | ES_MULTILINE
		/*允许多行(竖向滚动风格必须和允许多行风格结合使用才能生效)*/  //风格
		//并且只有配合滚动条才好玩
		| WS_HSCROLL/*横向滚动条*/ | WS_VSCROLL,/*竖向滚动条*/
		1000, 500,//坐标
		100, 100,//宽高
		hWnd, //父窗口句柄
		(HMENU)5001,
		g_hInstance,
		NULL);
	CreateWindow("Button",//类名,不能自己乱输入,必须是系统有的
		"获取文本框中文字",//按钮的名字
		WS_CHILD | WS_VISIBLE,//风格
		1000, 700,//坐标
		300,100,//宽高
		hWnd, //父窗口句柄
		(HMENU)5002,
		g_hInstance,
		NULL);
	CreateWindow("Edit","光谷小五郎",//文本编辑框中的默认内容
		WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL /*允许横向滚动*/ | ES_AUTOVSCROLL/*允许竖向滚动*/ | ES_PASSWORD//密码框
		/*允许多行(竖向滚动风格必须和允许多行风格结合使用才能生效)*/  //风格
		//并且只有配合滚动条才好玩
		| WS_HSCROLL/*横向滚动条*/ | WS_VSCROLL,/*竖向滚动条*/
		1000, 100,//坐标
		100, 100,//宽高
		hWnd, //父窗口句柄
		(HMENU)5003,
		g_hInstance,
		NULL);
	//6.组合框:下拉列表+文本编辑框
	CreateWindow("ComboBox",//类名,不能自己乱输入,必须是系统有的
		"简单组合框",//按钮的名字
		WS_CHILD | WS_VISIBLE | CBS_SIMPLE,//风格
		700, 100,//坐标
		100, 100,//宽高
		hWnd, //父窗口句柄
		(HMENU)6001,
		g_hInstance,
		NULL);
	//下拉组合框
	HWND simpleCombo = CreateWindow("ComboBox",//类名,不能自己乱输入,必须是系统有的
		"下拉组合框",//按钮的名字
		WS_CHILD | WS_VISIBLE| CBS_DROPDOWN /*下拉框*/ | WS_VSCROLL/*垂直滚动条*/,//风格
		700, 400,//坐标
		300, 100,//宽高
		hWnd, //父窗口句柄
		(HMENU)6001,
		g_hInstance,
		NULL);
	//给组合框添加选项
	char name[20];
	for (int i = 0; i < 7; i++) {
		memset(name, 0, 20);
		wsprintf(name, "%d娃", i + 1);
		SendMessage(simpleCombo, CB_ADDSTRING/*添加选项*/, 19, (LPARAM)name);
	}
}


LRESULT CALLBACK WndProc(HWND hWnd,//窗口句柄  
//CALLBACK表示是一个回调函数,LRESULT是函数返回值的类型,可以通过查看wc.lpfnWndProc的定义查看 
UINT code,//消息  msg.message
WPARAM wParam,//消息附加信息 
LPARAM lParam//消息附加信息 
) {
	HMENU hGet;
	RECT rect;
	

	//用switch case 来判断是什么消息 
	switch (code) {
	
	case WM_CONTEXTMENU:
		GetWindowRect(hWnd, &rect);//获取当前窗口客户区的矩形,传参给rect
		TrackPopupMenu(hRight, TPM_RIGHTBUTTON, LOWORD(lParam), HIWORD(lParam), 0, hWnd, &rect);//右键点击时显示菜单
		break;
#if 0
	case WM_RBUTTONUP://当单击右键并弹起时,会收到此消息
		//TrackPopupMenu()
		GetWindowRect(hWnd, &rect);//获取当前窗口客户区的矩形,传参给rect
		TrackPopupMenu(hRight, TPM_CENTERALIGN, rect.left+LOWORD(lParam),rect.top+HIWORD(lParam), 0, hWnd, &rect);//右键点击时显示菜单
		break;//用这种方式右键菜单弹出的位置有点问题,因为WM_RBUTTONUP的lParam中存储的是相对于桌面的xy坐标,需要用当前窗口即rect.left+LOWOR(lParam)转化成相对于窗口的。
#endif
		break;
	case WM_SYSCOMMAND://点击系统菜单项就会产生WM_SYSCOMMAND消息
		switch (wParam) {//不同的系统菜单项会产生不同的WM_SYSCOMMAND消息,这些消息的wParam中保存的菜单项id号不同
		case 1112://之前我们自己追加的菜单项id号为1112
			MessageBox(hWnd, "123", "系统菜单项", NULL);
			break;
		default:
			break;
		}

		break;
	case WM_KEYUP:
		break;
		
	case WM_KEYDOWN:
		switch (wParam) {
		case VK_UP:
			y -= 10;
			n = 0;
			break;
		case VK_DOWN:
			y += 10;
			n = 1;
			break;
		case VK_LEFT:
			x -= 10;
			n = 2;

			break;
		case VK_RIGHT:
			x += 10;
			n = 3;
			break;

		}

		break;
	case WM_COMMAND://当点击菜单项时会发送WM_COMMAND消息,由于不同的菜单项我们设置了不同的id,所以可以根据菜单项的id来区分
		wmId = LOWORD(wParam);//保存按钮和控件的Id
		wmEvent = HIWORD(wParam);//保存事件
		switch (wmId) {
		case 6001: {
			CHAR buff[256] = { 0 };
			HWND hCombo = GetDlgItem(hWnd, 6001);//得到句柄为hWnd的窗口中id为6001的控件的句柄
			if (wmEvent == CBN_SELCHANGE) {
				SendMessage(hCombo, WM_GETTEXT, 255, (LPARAM)buff);
				MessageBox(NULL, buff, NULL, NULL);
			}
			break; }
		case 5001:
			if (wmEvent == EN_CHANGE/*如果文本编辑框的内容有发生改变*/) {
				//MessageBox(NULL, "改变", "文本编辑框", NULL);
			}
			break;
		case 5002: {
			//获取文本框内容并显示
			HWND hEdit = GetDlgItem(hWnd, 5001); // 获取文本框句柄
			CHAR buff[256] = { 0 };
			RECT rect = { 0 };

			SendMessage(hEdit, WM_GETTEXT/*获取文本框内容*/, 255,(LPARAM)buff);//这里的wparam参数是获取的字符数量,lparam则是放到什么地方去
			//SendMessage(hEdit, EM_GETRECT, NULL, (LPARAM)&rect);//获取文本框的矩形信息
			//wsprintf(buff, "%d,%d,%d,%d", rect.top, rect.left, rect.bottom, rect.right)
			MessageBox(NULL, buff, "文本框内容", NULL);
			break; 
		}
		case 1001:
			if(wmEvent == STN_CLICKED){
			//MessageBox(NULL, "蔡徐坤好帅","单击控件",NULL);
				HICON hIcon1 = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON1));
				//获取静态位图框的句柄
				HWND hStaticWnd=GetDlgItem(hWnd,1002);//获得对话框的句柄,子窗口可以称为对话框,这里1002是静态位图框
				//向控件发消息
				SendMessage(hStaticWnd,STM_SETICON,(WPARAM)hIcon1,NULL);
			}
        else if (wmEvent == STN_DBLCLK) {//双击消息会覆盖第二个单击消息,但是第一个单击消息 不会被覆盖
		//MessageBox(NULL, "蔡徐坤超级帅", "双击控件", NULL);
		//MessageBox(NULL, "蔡徐坤好帅","单击控件",NULL);
		HICON hIcon2 = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SMALL));
		//获取静态位图框的句柄
		HWND hStaticWnd = GetDlgItem(hWnd, 1002);//获得对话框的句柄,子窗口可以称为对话框,这里1002是静态位图框
		//向控件发消息
		SendMessage(hStaticWnd, STM_SETICON, (WPARAM)hIcon2, NULL);
        }
			break;
		case 2001:
			/*即如果登录按钮按下,则A,B两个单选框的id,如果是第2次点击,则设置A被选中,第1次点击,则设置B被选中*/
			g_count++;
			HWND hA= GetDlgItem(hWnd, 2003);
			HWND hB = GetDlgItem(hWnd, 2004);
			HWND hC = GetDlgItem(hWnd, 2005);
			LRESULT ret = SendMessage(hC, BM_GETCHECK, BST_CHECKED, NULL);//返回C是否被选中
			//if (g_count % 2 == 0)
			if (ret==BST_UNCHECKED){//如果C没有被选中,则选中A
				SendMessage(hB, BM_SETCHECK, BST_UNCHECKED, NULL);
				SendMessage(hA, BM_SETCHECK, BST_CHECKED, NULL);
			}
			else {
				SendMessage(hA, BM_SETCHECK, BST_UNCHECKED, NULL);//取消A被选中
				SendMessage(hB, BM_SETCHECK, BST_CHECKED, NULL);//设置B被选中
			}
		
			break;
		}
		switch (wParam) {// 点击不同的菜单项,WM_COMMAND的附加消息wParam中存储的id号不同
		case 2522:
			MessageBox(hWnd, "切换角色为蔡徐坤", "恭喜", MB_OK);
			name0 = "cxk0.bmp";
			name1 = "cxk1.bmp";
			name2 = "cxk2.bmp";
			name3 = "cxk3.bmp";
			
			break;
		//点击 桃乃木香奈 2524 菜单项 设置 波多野结衣菜单项 2521 可选中(由灰色变成黑色)
		//点击 波多野结衣 2521 菜单项 设置 桃谷绘里香 2523 菜单项选中
		case 2524:
			hGet =GetSubMenu(GetMenu(hWnd),1);//GetMenu拿到的是窗口句柄为hWnd的窗口的顶层菜单的菜单句柄;以之作为参数去拿顶层菜单的弹出式菜单
			EnableMenuItem(hGet, 2521, MF_ENABLED);//设置波多野结衣菜单项为黑色
			break;
		case 2521:
			hGet = GetSubMenu(GetMenu(hWnd), 1);
			//通过id号来选中桃谷绘里香菜单项
			//CheckMenuItem(hGet, 2523, MF_CHECKED);//设置桃谷绘里香被选中
			//通过相对位置来选中桃谷绘里香 菜单项
			CheckMenuItem(hGet, 3, MF_CHECKED | MF_BYPOSITION);
			break;
		case 2525:
			hGet = GetSubMenu(GetMenu(hWnd), 1);
			switch (flag) {
			case 0:
				CheckMenuItem(hGet, 2522, MF_CHECKED);
				flag = 1;
				break;
			case 1:
				CheckMenuItem(hGet, 2522, MF_UNCHECKED);
				flag = 0;
				break;
			}
			break;


		}
		break;


	case WM_MOUSEMOVE:
		break;

	case WM_CREATE://代表窗口创建消息 
		OnCreate1(hWnd);
		OnCreate(hWnd, wParam, lParam);
		//帧:一秒钟切换图片数。
		//人眼可以识别的流畅动画,一秒钟16张图片以上。
		SetTimer(hWnd, 6666, 50, NULL);//定时器id6666,间隔50毫秒,
	
		break;
	case WM_TIMER:
		tietu(hWnd);//因为每隔50毫秒,发送一次定时器消息,所以每隔50毫秒切一次图
		break;
	case WM_PAINT://绘图消息
	{
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint(hWnd, &ps);//拿到设备DC,返回值为DC设备句柄
#if 0
		//1.创建画笔
		HPEN hPen0=CreatePen(PS_DASH, 10, RGB(255, 20, 20));//返回画笔对象的句柄
		HPEN hPen1 = CreatePen(PS_SOLID, 3, RGB(10, 10, 30));
		//2.设置画笔:即拿这支笔
		HGDIOBJ hOldpen=SelectObject(hdc, hPen0);
		
		
		/*
		HGDIOBJ 是一个类,是windows上所有GDI类型的基类,基类指针可以指向派生类的对象。HGDIOBJ x=HPEN hpen没有问题
		
		*/
		//3.画图
		
		MoveToEx(hdc, 30, 30, NULL);//画线,设置起始点
		LineTo(hdc, 600, 30);//lineto函数划线,只会设置划线的终点。
		//4.还原画笔
		SelectObject(hdc,hOldpen);
		//5删除画笔
		DeleteObject(hPen0);
		DeleteObject(hPen1);


#endif
/*
		//1创建画刷
		HBRUSH hBrush1=CreateSolidBrush(RGB(255, 0, 0));
		HBRUSH hBrush2 = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));//第一个参数为画刷的风格
        //2设置画刷到DC中
		HGDIOBJ hOldBrush = SelectObject(hdc, hBrush1);
		//3使用画刷
		RoundRect(hdc, 30, 30, 100, 100, 100, 100);//画椭圆矩形
		SelectObject(hdc, hBrush2);
		Rectangle(hdc, 150, 150, 300, 300);
		//4还原画刷
		SelectObject(hdc, hBrush2);
		//5删除画刷
		DeleteObject(hBrush2);
		EndPaint(hWnd, &ps);
*/
		
#if 0
//截屏:拿到操作系统当前屏幕某个区域内的图像
		HDC hScreenDc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);//第一个参数为设备,TEXT(“DISPLAY”)表示输出设备
		for (int y = 0; y < 300; y++) {
			for (int x = 0; x < 300; x++) {
				BitBlt(hdc, 0, 0, 300, 300,hScreenDc,0,0,SRCCOPY);//把hScreenDc中的内容画到hdc里面,从(0,0)画到(300,300),从hScreenDc的(0,0)开始去拿。画的方式SRCCOPY直接拷贝。
			}
		}
#endif
		//贴图
		//1.有图片
		//HBITMAP hBitmap1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1));//加载位图,只能加载bmp类型的图片
		HANDLE hBitmap1 = LoadImage(g_hInstance, "bk.bmp", IMAGE_BITMAP, 641, 480, LR_LOADFROMFILE);
		//2.创建兼容DC
		HDC hBuffDc = CreateCompatibleDC(hdc);
		//3.图片放入兼容DC//将图片里面的东西,放到内存中
		SelectObject(hBuffDc, hBitmap1);
	    //参数:当前程序实例句柄,资源id
		//loadImage()之前已经讲过了
		//4.贴图:将内存中的东西放到窗口中
		BitBlt(hdc, 0, 0,641,480,hBuffDc,0,0,SRCPAINT);
		//贴到哪里 贴到窗口的哪个坐标(x,y)  贴图的宽高  从哪里获取图片,从获取图片的哪个坐标开始截图 贴图方式      SRCAND透明贴图
		break;

	}


	case WM_DESTROY:
		PostQuitMessage(0);//PostQuitMessage函数发送一个WM_QUIT消息到线程消息队列并且立即返回
		break;
	default:
		return DefWindowProc(hWnd, code, wParam, lParam);//意味着开始下一次消息循环 
	}
	return DefWindowProc(hWnd, code, wParam, lParam);//意味着开始下一次消息循环 
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hParentInstance, LPSTR lpCmd, int len) {
	g_hInstance = hInstance;


	//1.写主函数
	//2.在主函数中注册窗口类  WNDCLASS WNDCLASSEX(64位扩展的) 
	WNDCLASSEX wc;//wc是一个窗口类 类型的 结构体,它里面有很多成员变量,一个一个给它们初始化就可以了
	wc.cbSize = sizeof(WNDCLASSEX);//窗口类大小 
	wc.cbClsExtra = NULL;//窗口类附加信息 即 对窗口类的说明 等于NULL表示没有附加信息 
	wc.cbWndExtra = NULL;//窗口附加信息 即对窗口的说明 
	wc.lpszClassName = "蔡徐坤大战av女优";//窗口类名,主要是为了标志版权 用spy++工具可以查看类名 
	//wc.hbrBackground=NULL;//背景 设置背景颜色
	wc.hbrBackground = (HBRUSH)GetStockObject(3);//百度查,记不住 
	wc.hCursor = NULL;
																	//wc.hIcon = NULL;//窗口的图标(任务栏) 用loadicon函数来加载图标:加载一个图标资源,并且返回这个图标资源的句柄。 
	wc.hIcon = NULL;
	//两种方式loadIcon和(HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,32,32,LR_LOADTANSPARENT);
	//加载方式:LR_LOADTANSPARENT资源方式加载,文件方式加载LOADFROMFILE

	wc.hIconSm = NULL;//小图标
	wc.hInstance = hInstance;//当前应用程序的实例句柄
	wc.lpfnWndProc = WndProc; //消息处理函数=你自己定义的消息处理函数的名字 
	wc.lpszMenuName = NULL; //菜单
	wc.style = CS_HREDRAW | CS_VREDRAW;//窗口风格=水平/垂直滚动条
	RegisterClassEx(&wc); //正式注册窗口类,只要把结构体wc的地址传入即可。 


	//3.创建窗口 CreateWindow  //HWND 窗口句柄类型 Handle Window 
	HWND hWnd = CreateWindowEx( //因为创建窗口函数会返回创建的窗口的句柄,所以首先定义好窗口句柄类型的变量。 
		NULL,//窗口的附加风格 
		wc.lpszClassName, //窗口类名 
		"蔡徐坤大战av女优",//窗口名 
		WS_OVERLAPPEDWINDOW,//窗口的风格 
		1000, 100,//窗口出现的位置 (x,y)
		600, 600,//窗口的宽高 
		NULL,//父窗口实例句柄 
		NULL,//窗口的菜单的句柄 
		hInstance,//窗口的实例句柄(当前应用程序实例句柄 
		NULL);//附加信息 消息是个结构体,消息有两个附加信息:lParam wParam 


		 /*如果创建窗口失败,则CreateWindow的返回值为NULL即0;
		  *如果创建窗口成功,则CreateWindow的返回值为所创建窗口的句柄
		  */
		  /*
		 if(NULL==hWnd){
			MessageBox(NULL,"创建窗口失败","警告",MB_OK);
			return -1;
		 }
		 else{
			MessageBox(NULL,"创建窗口成功","恭喜",MB_OK);
		 }
		*/

		//4.显示刷新窗口 ShowWindow updateWindow
	ShowWindow(hWnd, 5);//传入窗口的句柄即可。 
	UpdateWindow(hWnd); //传入窗口的句柄即可。 
	AllocConsole();//得到命令行窗口使用权限
	g_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//用函数得到命令行窗口句柄,赋值给全局变量g_hConsole

	//5.定义窗口的消息处理函数

	//消息循环是一个死循环,永远不会结束,除非。。。你写一个语句break 
	while (1) {
		//获取消息 
		//GetMessage(&msg, NULL, NULL, NULL);//GetMessage函数是一个阻塞函数,如果接收一个消息所用的时间过长,在此期间内,如果有另一个消息被发送,就会接受不到这个消息
		if (PeekMessage(&msg, NULL, NULL, NULL, NULL))//最后一个参数表示是否删除消息
		/*PeekMessage的工作原理:非阻塞方式接受消息,主要查看是否有消息,不会将消息存入MSG结构体中,GetMessage函数负责将消息存入MSG结构体中。
		Peekmessage会检查消息队列,如果消息队列中有消息,函数就会查看最后一个参数,
		如果最后一个参数为false或者NULL,直接返回1
		如果最后一个参数为true,从消息队列中删除消息,然后返回1
		如果消息队列中没有消息,直接返回0

		*/ {
			if (0 == GetMessage(&msg, NULL, NULL, NULL)) break;
			/*GetMessage工作原理:
			GetMessage从消息队列中获取一个消息存放到MSG结构体中。
			如果消息队列中有消息,把消息存入MSG,删除当前程序消息队列中的消息,返回非0
			直到遇到WM_QUIT消息才返回0.注意:关闭窗口不会发送WM_QUIT消息,只会发送WM_DESTROY消息,只有在消息处理函数中定义当收到WM_DESTROY时,向消息队列中添加WM_QUIT消息,
			才能通过if(0 == GetMessage(&msg, NULL, NULL, NULL)) break;退出循环。
			如果当前程序消息队列中没有消息,就去系统消息队列中看有没有消息。如果系统消息队列
			里面有消息,就把系统消息队列中的消息放入当前程序消息队列。如果系统消息队列中没有消息,就
			检查窗口是否需要重新绘制。如果需要重新绘制,操作系统发送WM_PAINT消息,如果不需要重新绘制
			查看是否有定时器,如果有定时器,处理定时器消息,如果没有定时器,优化资源,处理内存,继续等待。
			消息循环处理消息的次数可能小于消息处理函数处理消息的次数,因为其他应用程序的消息也可能发送给消息处理函数处理。


			*/
			/*
			if (msg.message == WM_QUIT) { //WM_QUITE消息表示整个窗口退出
				break;
			}
			*/

			//翻译消息 
			TranslateMessage(&msg);//翻译消息
			/*消息的翻译主要针对键盘消息,键盘消息只有两个:
			WM_TDOWN
			WM_TUP
			if(msg.message==WM_KEY 按键消息){
			   if(是否可见字符){//可见字符即代表字符有回显,例如F1F2..PgUp等不是可见字符。
			   //如果是可见字符,代表应该告诉应用程序,用户按键是用来编辑,发送的是一个字符,否则,就认为用户按键是发送一个指令。
			   //如果用户发送的是一个字符,就需要翻译一下
				 if(Caps Lock是否按下){
					PostMessage(大写字母消息);//发送大写字母消息
				 }else{
				   PostMessage(小写字母消息);//发送小写字母消息
				 }

			   }
			 }
			 return;
			*/
			DispatchMessage(&msg);//派发消息,群发消息,给当前所有的应用程序都发送。而PostMessage表示只对当前应用程序的消息处理函数发送消息。


		}

	}
	//6.消息循环    循环 接受消息 翻译消息 派发消息

	//点击动作 操作系统产生消息 发给窗口应用程序,应用程序里面的“消息循环”接收消息,调用对应的消息处理函数,产生对应的响应动作。 

	return 0;

}
#include <windows.h>
#include <cstdio>
#include <iostream>
using namespace std;
HINSTANCE g_hInstance;

template <typename T>
void MyPrintf(char* str,T data1,T data2){
	AllocConsole();
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	//HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
	//HANDLE hError = GetStdHandle(STD_ERROR_HANDLE);
	char buff[1024]={0};
	sprintf(buff,str,data1,data2);
	WriteConsole(hOutput,buff,strlen(buff),NULL,NULL);
	return;
}
template <typename T>
void MyPrintf(char* str,T data){
	AllocConsole();
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	//HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
	//HANDLE hError = GetStdHandle(STD_ERROR_HANDLE);
	char buff[1024]={0};
	sprintf(buff,str,data);
	WriteConsole(hOutput,buff,strlen(buff),NULL,NULL);
	return;
}

#if 1
struct task{
	char* content;
	int importance;
	task(){
		memset(this,0,sizeof(task));
	}
	task(char* str,int _importance);
};
task::task(char* str,int _importance){
	int len = strlen(str);
	content = (char*)malloc(sizeof(char)*(len+1));
	if(content == NULL){
		MyPrintf("%s\n","开内存失败!");
		return;
	}
	memset(content,0,sizeof(char)*(len+1));
	strcpy(content,str);
	importance = _importance;
}

class taskQueue{
	task* pBuff;
	int len;
	int capacity;
public:
	taskQueue(){memset(this,0,sizeof(taskQueue)};
	bool insertTask(task t);
	void displayTask();
	bool popTask();
	void sortTaskByImportance(); 
}
bool taskQueue::insertTask(task t){
	len++;
	if(len >= capacity){
		capacity += (capacity == 0)?1:capacity>>1;
		task* pNew = (task*)malloc(sizeof(task)*capacity);
		if(pNew == NULL){
			return false;
		}
		memset(pNew,0,sizeof(task)*capacity);
		memcpy(pNew,pBuff,sizeof(task)*(len-1));
		free(pBuff);
		pBuff = pNew;
	}
	pBuff[len-1] = t;
	return true;
}
void taskQueue::displayTask(){
	for(int i=0;i<len;i++){
		MyPrintf("第%d个任务-",i);
		MyPrintf("content:%s-importance:%d\n",pBuff[i].content,pBuff[i].importance);
	}
	return;
}

#endif




void OnCreate(HWND hwnd){
	CreateWindow("Static","任务队列:\n高数\nC语言\n电路基础\n",WS_VISIBLE|WS_CHILD|SS_CENTER,40,20,260,320,hwnd,(HMENU)1000,g_hInstance,NULL);
	CreateWindow("Edit","请输入要添加待办事项...",WS_CHILD|WS_VISIBLE|SS_CENTER,40,350,220,30,hwnd,(HMENU)1001,g_hInstance,NULL);
	CreateWindow("Edit","请输入该事项的重要程度(用整数表示)",WS_CHILD|WS_VISIBLE|SS_CENTER,40,385,220,30,hwnd,(HMENU)1003,g_hInstance,NULL);
	CreateWindow("Button","添加",WS_CHILD|WS_VISIBLE,265,350,35,30,hwnd,(HMENU)1002,g_hInstance,NULL);
	return;
}
void displayCursorPos(LPARAM lParam){
	POINT pos;
	pos.y = HIWORD(lParam);
	pos.x = LOWORD(lParam);
	MyPrintf("光标的客户区坐标 {x:%d,y:%d}\n",pos.x,pos.y);
	return;
}
void OnCommand(HWND hwnd,WPARAM wParam){
	int wmId = LOWORD(wParam);
	int wmEvent = HIWORD(wParam);
	switch(wmId){
		case 1002://添加按钮
			HWND hEdit = GetDlgItem(hwnd,1001);
			char buff[1024] = {0};
			SendMessage(hEdit,WM_GETTEXT,255,(LPARAM)buff);
			//MyPrintf("文本编辑框中的内容为:%s\n",buff); 
			task(buff,)
	}
	return;
}

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
	switch(Message) {
		case WM_CREATE:
			OnCreate(hwnd);
			break;
		/* trap the WM_CLOSE (clicking X) message, and actually tell the window to close */
		case WM_CLOSE: {
			DestroyWindow(hwnd);
			break;
		}
		
		/* Upon destruction, tell the main thread to stop */
		case WM_DESTROY: {
			PostQuitMessage(0);
			break;
		}
		case WM_MOUSEMOVE:
			displayCursorPos(lParam);
			break;
		case WM_COMMAND:
			OnCommand(hwnd,wParam);
			break;
		/* All other messages (a lot of them) are processed using default procedures */
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	g_hInstance = hInstance;
	WNDCLASSEX wc; /* A properties struct of our window */
	HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
	MSG Msg; /* A temporary location for all messages */

	/* zero out the struct and set the stuff we want to modify */
	memset(&wc,0,sizeof(wc));
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.lpfnWndProc	 = WndProc; /* This is where we will send messages to */
	wc.hInstance	 = hInstance;
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	
	/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszClassName = "WindowClass";
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);

	if(!RegisterClassEx(&wc)) {
		MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		640, /* width */
		480, /* height */
		NULL,NULL,hInstance,NULL);

	if(hwnd == NULL) {
		MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}

	/*
		This is the heart of our program where all input is processed and 
		sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
		this loop will not produre unreasonably CPU usage
	*/
	while(GetMessage(&Msg, NULL, 0, 0) > 0) { /* If no error is received... */
		TranslateMessage(&Msg); /* Translate keycodes to chars if present */
		DispatchMessage(&Msg); /* Send it to WndProc */
	}
	return Msg.wParam;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

win32Day06:控件 的相关文章

  • cudnn.deterministic = True 固定随机种子

    随机数种子seed确定时 xff0c 模型的训练结果将始终保持一致 随机数种子seed确定时使用相同的网络结构 xff0c 跑出来的效果完全不同 xff0c 用的学习率 xff0c 迭代次数 xff0c batch size 都是一样 to
  • torch.cuda.is_available(),torch.cuda.device_count(),torch.cuda.get_device_name(0)

    torch cuda is available cuda是否可用 xff1b torch cuda device count 返回gpu数量 xff1b torch cuda get device name 0 返回gpu名字 xff0c
  • windows, 放方向键设置为vim格式,autohotkey-windows

    安装 Autohotkey https www autohotkey com download 设置快捷键 随便找个目录 鼠标右键新建一个autohotkey的脚本 映射一个键 上左下右 经常打字的人都知道 我们编辑文本时要上下左右移动光标
  • window设置快捷键左右方向键

    autohotkey windows快捷键设置神器 使用方法 地址
  • Linux系统无痛编译安装LLVM简明指南

    1 编译与预编译版本选择 如果对LLVM没有特别需求 xff0c 只是当作一般编译器使用 xff0c 安装预编译版也足以应付场面 xff1b 如果需要对LLVM作个性化定制 xff0c 或基于LLVM开发 xff0c 或学习LLVM源码 x
  • ROS:订阅话题并发布(订阅amcl_pose数据并发布)

    一 创建节点 cd span class token operator span span class token operator span catkin ws span class token operator span src cat
  • 什么是API,SDK和API之间有什么关系呢?

    随着软件规模的日益庞大 xff0c 常常需要把复杂的系统划分成小的组成部分 xff0c 编程接口的设计十分重要 xff0c 程序设计的实践中 xff0c 编程接口的设计首先要使软件系统的职责得到合理划分 xff0c 良好的接口设计可以降低系
  • PX4下gazebo 仿真 offboard模式(ubuntu18.04)

    PX4下gazebo 仿真 offboard模式 xff08 ubuntu18 04 xff09 1 ros与gazebo安装 这里不多说了 xff0c 上网找教程或者按照ros官网教程安装完成ros melodic的完整版 xff0c g
  • px4与gazebo的多无人机编队仿真,offboard模式

    px4下基于ros和gazebo的多无人机编队仿真 xff0c offboard模式 单机的offboard仿真见https blog csdn net weixin 43409270 article details 114585397 多
  • 软件工程面向对象方法、Coad、Booch、OMT、UML方法

    1 Booch方法 Booch最先描述了面向对象的软件开发方法的基础问题 xff0c 指出面向对象开发是一种根本不同于传统的功能分解的设计方法 面向对象的软件分解更接近人对客观事务的理解 xff0c 而功能分解只通过问题空间的转换来获得 B
  • 机器人地面站-[QGroundControl源码解析]-[1]

    目录 前言 一 CmdLineOptParser 二 JsonHelper 三 KMLDomDocument 四 ShapeFileHelper 五 SHPFileHelper 六 KMLHelper 七 LogCompressor 总结
  • 机器人地面站-[QGroundControl源码解析]-[2]

    目录 前言 一 QGC 二 QGCComboBox 三 QGCFileDownload 四 QGCLoggingCategory 五 QGCMapPalette 六 QGCPalette 七 QGCQGeoCoordinate 八 QGCT
  • 机器人地面站-[QGroundControl源码解析]-[9]-[Camera]

    目录 前言 一 QGCCameraManager 二 QGCCameraIO 三 QGCCameraControl 前言 本篇介绍Camera文件夹下的内容 xff0c 该文件夹下又三个类文件 xff0c 分别是QGCCameraManag
  • C++开发精髓 阅读笔记

    第三章 pstack的使用 将C 43 43 类对象实例指针作为线程函数的参数 bind函数 span class token keyword auto span newCallable span class token operator
  • js逆向工具-油猴Tampermonkey脚本hook案例

    目录 一 油猴下载与安装二 油猴脚本免费使用网站三 油猴脚本编写介绍1 添加新脚本2 油猴脚本注释内容解释3 编写油猴脚本的基本步骤4 油猴脚本调试测试 四 hook之js逆向案例1 hook之window属性案例2 hook之cookie
  • js逆向案例-rus4逻辑学习

    目录 一 RS4特点二 网站请求流程特点三 网站加载js的顺序四 正式逻辑的研究1 cookie如何定位 xff1f 2 扣函数缺啥补啥注意事项 xff1f 3 如何获取 96 ts动态变量 96 值 xff1f 4 如何定位 96 MmE
  • js逆向案例-初学signature

    一 反爬点 案例网址 xff0c 向下滚动加载页面时的请求参数反爬signature xff0c 明显的特征 xff1a acrawler js以及window jsvmprt 34 二 反爬分析 参考文章1 xff0c 参考文章2 xff
  • Android逆向基础入门

    目录 一 基础App数据抓取1 App常用抓包工具2 fiddler抓包工具3 mitmdump抓包工具4 charles抓包工具5 uiautomatorviewer appium自动化工具6 Airtest自动化工具 二 js逆向与ap
  • 自动化测试工具-Airtest

    目录 一 Airtest介绍与安装二 Airtest基于图像识别自动控制手机App流程三 Airtest基于Poco的UI组件自动化控制App流程四 Airtest实现手机群控操作 一 Airtest介绍与安装 主要介绍区别 xff0c 以

随机推荐

  • Docker桌面版安装与使用(windows)

    目录 一 Docker概念二 下载安装三 docker镜像安装与操作四 制作自己的python镜像容器五 目录挂载六 多容器通信七 Docker Compose管理多个容器运行八 发布和部署九 备份数据迁移 一 Docker概念 1 Doc
  • Gradio 机器学习和数据科学开源 Python 库

    Gradio是一个开源的 Python 库 xff0c MIT的开源项目 xff0c 用于构建机器学习和数据科学演示和 Web 应用 Gradio的定位类似于Streamlit xff0c 但是更轻量 xff0c 因为它推荐的应用场景都是对
  • k8s安装

    目录 一 K8s概念二 minikube安装三 部署应用到集群中四 Service五 k8s部署爬虫1 意义 一 K8s概念 参考文章 xff0c 参考视频它是一个为 容器化 应用提供集群部署和管理的开源工具 xff0c 由 Google
  • 编程工具-GPT来AI编程代码

    一 安装介绍 1 https www cursor so 下载安装 xff0c 重要的说三遍 xff08 目前免费 xff01 免费 xff01 免费 xff01 xff09 xff0c 支持多平台 Mac Windows Linux xf
  • 某wipo专利_六宫格/cookie/css

    这里写目录标题 一 案例分析二 六宫格验证码三 列表页搜索式302四 详情页css链接cookie刷新 一 案例分析 案例网址 xff1a 案例网址 反爬点 xff1a 六宫格验证码 cookie反爬 时间强制等待 session数据强绑定
  • Python之urlencode()使用

    urlencode 传入参数类型 xff1a 字典功能 xff1a 将存入的字典参数编码为URL查询字符串 xff0c 即转换成以key1 61 value1 amp key2 61 value2的形式导入 xff1a from urlli
  • Python之Md5使用等加密

    目录 一 Python之md5使用二 Python之sha1使用三 Python之base64使用四 Python之rsa使用五 Python之aes des 一 Python之md5使用 功能 xff1a MD5签名是一个哈希函数 xff
  • Python之quote()使用

    quote 传入参数类型 xff1a 字符串功能 xff1a 将单个字符串编码转化为 xx 的形式导入 xff1a from urllib parse import quotePs xff1a url多个字符串编码用urlenocde 函数
  • ( 数组和矩阵) 645. 错误的集合 ——【Leetcode每日一题】

    645 错误的集合 难度 xff1a 简单 集合 s 包含从 1 到 n 的整数 不幸的是 xff0c 因为数据错误 xff0c 导致集合里面某一个数字复制了成了集合里面的另外一个数字的值 xff0c 导致集合 丢失了一个数字 并且 有一个
  • Kalman滤波(Part-1:信号模型基础)

    Kalman Filters Dynamical Signal Models 一阶高斯 马尔可夫过程 first order Gauss Markov process 描述采样点之间 xff08 相邻 xff09 的相关性 xff1a s
  • 【STM32】关于keil5中下载按钮灰色及出现#error “Please select first the target STM32F4xx devic....错误的解决方法

    解决首次运行报错问题 近期在网上购买了一个WIFI模组 xff0c 例程是使用HAL库编写的 xff0c 首次编译的时候出现USER stm32f4xx h 193 error 35 error directive 34 Please se
  • 【STM32】F429单片机的时钟系统浅析

    先把429的时钟树附上 xff1a 乍一看是不是很懵逼 xff0c 我也很懵逼 一堆乱七八糟的玩意 xff0c ST公司是真的狗 本文是基于库函数SetSysClock 展开的 xff0c 配合该函数使用时钟树效果更佳O O 讲解之间说一个
  • x-easypdf 基于pdfbox/fop 封装的框架

    x easypdf 是一个基于 pdfbox fop 二次封装的框架 xff0c 目前拥有两大模块 xff1a pdfbox 模块 与 fop 模块 pdfbox 模块 主打 pdf 编辑功能 xff0c 以组件化的形式进行 pdf 的构建
  • 【STM32】利用定时器实现最基本的定时功能(HAL)

    定时器简介 STM32F429单片机有许多定时器Timer xff0c 主要分成三类 xff0c 基本定时器 xff1b 通用定时器和高级定时器 三种类型的定时器功能由少变多 xff0c 高级定时器包含了低级定时器的功能 基本定时器 xff
  • 【STM32】通俗易懂的讲解回调函数

    转载 xff1a https blog csdn net vincent040 article details 50832955 回调函数在程序开发中是一个非常重要的概念 xff0c 所谓的回调其实就是不同程序模块之间的接口和约定 xff0
  • 【树莓派】设置树莓派开机自动运行python脚本

    近期因科研需要 xff0c 需命令树莓派开机后无需进行任何操作自动运行一个python脚本 xff0c 经查阅部分资料后实现了该功能 xff0c 为方便以后查看特此记录一下 1 打开cmd xff0c 输入 sudo vim span cl
  • 部分机器人领域顶会顶刊官网及22年顶会召开时间

    顶刊 Science Robotics AAAS The International Journal of Robotics Research IJRR Journal of Forestry Research JFR IEEE Trans
  • 服务器非root下安装Python cyglfw3库

    服务器非root下安装Python cyglfw3库 在服务器中跑PVNet的代码时遇到的 xff0c 废了比较大的劲才解决 xff0c 特意记录一下解决过程 如果你有sudo权限直接使用sudo apt get install libgl
  • FFB6D搭建环境

    文章目录 FFB6D搭建环境搭建前的准备 根据需要选择性浏览 安装apex安装normal speed安装opencv3 安装pybind11安装normal speed 安装RandLA运行代码前的准备运行代码有疑问多多交流 xff0c
  • win32Day06:控件

    1 什么是控件 xff1f 控件是具备特殊功能的窗口 xff0c 并且有模板 控件的特性 xff1a 一定是子窗口 和创建主窗口一样 xff0c 都是使用CreateWindow函数来创建 xff08 控件这种 xff09 子窗口和主窗口的