• Win32第一个窗口程序


    完美一点

    #include <windows.h>
    
    HINSTANCE g_hInst = NULL;
    
    //2. 定义窗口处理函数
    LRESULT CALLBACK WndProc(
    						HWND hWnd,
    						UINT nMsg,
    						WPARAM wParam,
    						LPARAM lParam
    						)
    {
    	switch(nMsg)
    	{
    		case WM_DESTROY:
    			PostQuitMessage(0);
    			return 0;
    	}
    	return DefWindowProc(hWnd, nMsg, wParam, lParam);
    }
    
    // 3. 创建窗口类型并注册窗口类型
    BOOL MyRegister(LPSTR pszClassName)
    {
    	WNDCLASS wc = {0};
    	ATOM nAtom = 0;
    
    	//构造注册窗口的参数
    	wc.style         = CS_VREDRAW|CS_HREDRAW;
    	wc.lpfnWndProc   = WndProc;
    	wc.cbClsExtra    = 0;
    	wc.cbWndExtra    = 0;
    	wc.hInstance     = g_hInst;
    	wc.hIcon         = NULL;
    	wc.hCursor       = NULL;
    	wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
    	wc.lpszMenuName  = NULL;
    	wc.lpszClassName = pszClassName;
    	//注册窗口
    	nAtom = RegisterClass( &wc );
    	if( 0 == nAtom )
    	{
    		MessageBox( NULL, "Register Failed", "Error", MB_OK|MB_ICONWARNING );
    		return FALSE;
    	}
    	else
    	{
    		MessageBox( NULL, "Register Successed", "Successed", MB_OK );
    	}
    	return TRUE;
    }
    
    //4. 窗口创建
    HWND MyCreate(LPSTR pszClassName)
    {
    	HWND hWnd = NULL;
    
    	hWnd = CreateWindow(pszClassName, "CntfWindows",
    		WS_OVERLAPPEDWINDOW, 300, 300, 800, 600, NULL, NULL,
    		g_hInst, NULL);
    
    
    	if(hWnd == NULL)
    	{
    		MessageBox(NULL, "CreateWindows Failed", "Errors", MB_OK);
    		return FALSE;
    	}
    	MessageBox(NULL, "CreateWindows Successed", "Successed", MB_OK);
    	return hWnd;
    }
    
    //5. 窗口显示
    void DisplayWnd( HWND hWnd)
    {
    	// 显示窗口
    	ShowWindow(hWnd, SW_SHOW);
    	// 更新窗口
    	UpdateWindow(hWnd);
    }
    
    //6. 消息处理
    void Message()
    {
    	MSG msg = {0};
    	//循环处理消息和获取消息
    	while(GetMessage(&msg, NULL, 0, 0))
    	{
    		//派发消息
    		DispatchMessage(&msg);
    	}
    }
    
    //1. WinMain 入口函数
    int APIENTRY WinMain(HINSTANCE hInst,
    					 HINSTANCE hPrevInst,
    					 LPSTR pszCmdLine,
    					 int nShowCmd)
    {
    	HWND hWnd = NULL;
    	g_hInst = hInst;
    
    	// 注册窗口类型
    	MyRegister("WindowsCntf");
    
    	// 创建窗口
    	hWnd = MyCreate("WindowsCntf");
    
    	// 显示窗口
    	DisplayWnd(hWnd);
    
    	// 消息处理
    	Message();
    
    	return 0;
    }
    
    /*
    编译
    cl cswin32.c /c
    链接
    link cswin32.obj user32.lib
    执行
    cswin32.exe
    
    1. 入口函数WinMain
    
    2.窗口处理函数
         当窗口处理消息事件时,系统调用该函数
       	LRESULT CALLBACK WindowProc(
    	  HWND hwnd,      // 窗口的句柄
      	UINT uMsg,      // 消息的ID号
      	WPARAM wParam,  // 消息所对应的参数
      	LPARAM lParam   // 消息所对应的参数
    		);
    
    3.注册窗口类型
        typedef struct _WNDCLASS { 
        UINT    style;  //窗口类的风格
        WNDPROC lpfnWndProc; //窗口处理函数
        int     cbClsExtra; //窗口类附加数据大小
        int     cbWndExtra; //窗口附加数据大小
        HANDLE  hInstance; //当前应用程序的实例句柄
        HICON   hIcon; //窗口图标
        HCURSOR hCursor; //窗口的鼠标
        HBRUSH  hbrBackground; //窗口的背景画刷
        LPCTSTR lpszMenuName; //菜单
        LPCTSTR lpszClassName; //类型名称
        } WNDCLASS;
    
     注册函数 RegisterClass
    
    4.创建窗口
         HWND CreateWindow(
      		LPCTSTR lpClassName,  //窗口类型名称
      		LPCTSTR lpWindowName, //窗口名称
      		DWORD dwStyle,        //窗口类型
      		int x,                //窗口的左上角X坐边
      		int y,                //窗口的左上角X坐边
      		int nWidth,           //窗口的宽度
      		int nHeight,          //窗口的高度
      		HWND hWndParent,      //父窗口句柄
      		HMENU hMenu,          //窗口菜单句柄
      	  HANDLE hInstance,     //应用程序的实例句柄
      	  LPVOID lpParam        //创建的参数,一般为NULL
    		  );
    5.显示窗口
         ShowWindow 显示窗口
            BOOL ShowWindow(
      			HWND hWnd,     //显示的窗口句柄
      		  int nCmdShow   //显示的方式
    			  );
         UpdateWindow 刷新窗口
    
    6.消息处理
         GetMessage 获取消息
       	 DispatchMessage 派发消息
       
    7.程序退出
         窗口销毁时,退出程序。在WndProc中实现。
            WM_DESTROY: 当窗口销毁时,会调用WndProc
              传递给使用者。
            PostQuitMessage:发送一个退出消息。
    		
    		
        4.1 资源和资源脚本
            资源:ICON/CUSRUR/BITMAP/MENU......
            资源脚本:扩展名为rc文件
        4.2 编译资源
            rc.exe 编译资源,生成res的文件
        4.3 链接资源
            使用link将res文件链接到程序当中
            
        手动添加ico图标操作步骤
        1.新建一个rc的扩展名文件,放一个图标在当前目录下然后编辑这个文件添加
        下面一句话
        228 ICON "cs.ico"
        上面228是编号,ICON是类型,最后面那个是图标的具体位置
        2.使用rc.exe进行编译
        rc cswin32.rc
        3.编译写好的Win32程序的代码
        cl createWin32Windows.c /c
        4.链接上面的Win32程序
        link createWin32Windows.obj cswin32.RES user32.lib
        5.上面没有问题就成功了
    		
     */
    
    

    滴水Win32好理解

    1.第一个图形界面程序
    
    步骤1:创建Windows应用程序  选择空项目
    
    步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件
    
    步骤3:在新的cpp文件中添加:#include <Windows.h>
    
    并添加入口函数:
    
    int CALLBACK WinMain(  						CALLBACK 是一个宏
    	_In_  HINSTANCE hInstance,  			#define CALLBACK    __stdcall
    	_In_  HINSTANCE hPrevInstance,
    	_In_  LPSTR lpCmdLine,
    	_In_  int nCmdShow
    	)  					                    所有的Win32 API函数都遵循该约定
    {
    
    	return 0;
    }
    
    步骤4:设计窗口类
    
    代码:
    
    //窗口的类名
    TCHAR className[] = "My First Window";
    
    // 创建窗口类的对象
    WNDCLASS wndclass = {0};						//一定要先将所有值赋值
    wndclass.hbrBackground = (HBRUSH)COLOR_MENU;	//窗口的背景色
    wndclass.lpfnWndProc = WindowProc;				//窗口过程函数
    wndclass.lpszClassName = className;				//窗口类的名字
    wndclass.hInstance = hInstance;					//定义窗口类的应用程序的实例句柄
    
    --------------------------------------------------------------------------------
    LRESULT CALLBACK WindowProc(
      HWND hwnd,      // handle to window
      UINT uMsg,      // message identifier
      WPARAM wParam,  // first message parameter
      LPARAM lParam   // second message parameter
    );
    --------------------------------------------------------------------------------
    
    typedef struct _WNDCLASS {
        UINT       style;
        WNDPROC    lpfnWndProc;
        //窗口产生消息的时候,有哪个函数去处理,(窗口消息的处理函数)
        int        cbClsExtra;
        int        cbWndExtra;
        HINSTANCE  hInstance;          //当前的窗口属于哪个应用程序
        HICON      hIcon;             //窗口上面图片的标识,就是那个小图标
        HCURSOR    hCursor;          //窗口里面出现鼠标,这个鼠标的形状是什么样的
        HBRUSH     hbrBackground;   //窗口的背景色是什么样
        LPCTSTR    lpszMenuName;    //窗口如果需要有菜单,必须告诉我菜单的名字
        LPCTSTR    lpszClassName;  //给我一个名字,必须有
    } WNDCLASS, *PWNDCLASS;
    
    步骤5:注册窗口类
    
    RegisterClass(&wndclass);
    
    步骤6:创建窗口
    
    // 创建窗口
       HWND hwnd = CreateWindow(
            className,				            //类名
            TEXT("我的第一个窗口"),				//窗口标题
            WS_OVERLAPPEDWINDOW,				//窗口外观样式
            10,				                    //相对于父窗口的X坐标
            10,				                    //相对于父窗口的Y坐标
            600,				                //窗口的宽度
            300,				                //窗口的高度
            NULL,				                //父窗口句柄,为NULL
            NULL,				                //菜单句柄,为NULL
            hInstance,				            //当前应用程序的句柄
            NULL);				                //附加数据一般为NULL
    
        if(hwnd == NULL)					    //是否创建成功
            return 0;
    
    步骤7:显示窗口
    
    // 显示窗口
    ShowWindow(hwnd, SW_SHOW);
    
    步骤8:消息循环
    
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
    	TranslateMessage(&msg);
    	DispatchMessage(&msg);
    }
    
    步骤9:回调函数
    
    /*
    窗口消息处理程序 窗口回调函数:
    
    1.窗口回调函数处理过的消息,必须传回0.
    
    2.窗口回调不处理的消息,由DefWindowProc来处理.
    */
    
    LRESULT CALLBACK WindowProc(
    							IN  HWND hwnd,
    							IN  UINT uMsg,
    							IN  WPARAM wParam,
    							IN  LPARAM lParam
    							)
    {
    	switch(uMsg)
    	{
    		//窗口消息
    	case WM_CREATE:
    		{
    			DbgPrintf("WM_CREATE %d %d\n",wParam,lParam);
    			CREATESTRUCT* createst = (CREATESTRUCT*)lParam;
    			DbgPrintf("CREATESTRUCT %s\n",createst->lpszClass);
    
    			return 0;
    		}
    	case WM_MOVE:
    		{
    			DbgPrintf("WM_MOVE %d %d\n",wParam,lParam);
    			POINTS points = MAKEPOINTS(lParam);
    			DbgPrintf("X Y %d %d\n",points.x,points.y);
    
    			return 0;
    		}
    	case WM_SIZE:
    		{
    			DbgPrintf("WM_SIZE %d %d\n",wParam,lParam);
    			int newWidth  = (int)(short) LOWORD(lParam);
    			int newHeight  = (int)(short) HIWORD(lParam);
    			DbgPrintf("WM_SIZE %d %d\n",newWidth,newHeight);
    
    			return 0;
    		}
    	case WM_DESTROY:
    		{
    			DbgPrintf("WM_DESTROY %d %d\n",wParam,lParam);
    			PostQuitMessage(0);
    
    			return 0;
    		}
    		//键盘消息
    	case WM_KEYUP:
    		{
    			DbgPrintf("WM_KEYUP %d %d\n",wParam,lParam);
    
    			return 0;
    		}
    	case WM_KEYDOWN:
    		{
    			DbgPrintf("WM_KEYDOWN %d %d\n",wParam,lParam);
    
    			return 0;
    		}
    		//鼠标消息
    	case WM_LBUTTONDOWN:
    		{
    			DbgPrintf("WM_LBUTTONDOWN %d %d\n",wParam,lParam);
    			POINTS points = MAKEPOINTS(lParam);
    			DbgPrintf("WM_LBUTTONDOWN %d %d\n",points.x,points.y);
    
    			return 0;
    		}
    	}
    	return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }
    
    --------------------------------------------------------------------------------
    
    课堂练习测试代码
    
    #include "stdafx.h"
    
    LRESULT CALLBACK WindowProc(
                                IN  HWND hwnd,
                                IN  UINT uMsg,
                                IN  WPARAM wParam,
                                IN  LPARAM lParam
                                );
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
     	// TODO: Place code here.
    
        /*
        第一步:创建Windows应用程序,选择空项目
        第二步:在新建项窗口中选中C++代码文件,创建一个新的cpp文件
        第三步:在新的cpp文件添加
        #include <windows.h> 然后再添加入口函数
    
        并添加入口函数:
        // CALLBACK 是一个宏
        // #define CALLBACK    __stdcall
    
        int CALLBACK WinMain(
        _In_  HINSTANCE hInstance,
        _In_  HINSTANCE hPrevInstance,
        _In_  LPSTR lpCmdLine,
        _In_  int nCmdShow
        )
        // 所有的Win32 API函数都遵循该约定
        {
          return 0;
        }
    
        上述3个步骤,可以直接新建选择一个入口函数模板即可
        */
        //4.第四步,设计窗口类
    
        // 窗口的类名称
        TCHAR className[] = "My First Windows";
    
        // 创建窗口类的对象,创建一个自己的窗口
        //WNDCLASS wndclass;// 这里如果是左边这样写,那么编译链接成功窗口出不来
        //所以必须要把wndclass里面的每个参数都赋值,不使用也要赋值为0
        //简便的方式就是加上{0}
        WNDCLASS wndclass = {0};
        wndclass.hbrBackground = (HBRUSH)COLOR_MENU; //指定一个背景色
        wndclass.lpfnWndProc = WindowProc; //消息处理函数
        //上面表示 当前应用程序一旦有事件被触发的时候,由哪个程序去处理她,这里是WindowProc函数来处理
        wndclass.lpszClassName = className; //给当前窗口取一个名字
        wndclass.hInstance = hInstance; //当前的窗口是哪个应用程序的,也就是ImageBase的值
    
        //5.第五步 注册窗口类
        RegisterClass(&wndclass);
    
        //6.创建窗口
    
        HWND hwnd = CreateWindow(
            className,				            //类名
            TEXT("我的第一个窗口"),				//窗口标题
            WS_OVERLAPPEDWINDOW,				//窗口外观样式
            100,				                    //相对于父窗口的X坐标
            100,				                    //相对于父窗口的Y坐标
            600,				                //窗口的宽度
            300,				                //窗口的高度
            NULL,				                //父窗口句柄,为NULL
            NULL,				                //菜单句柄,为NULL
            hInstance,				            //当前应用程序的句柄
            NULL);				                //附加数据一般为NULL
    
        if(hwnd == NULL)					    //是否创建成功
            return 0;
    
        // 7.显示窗口
        ShowWindow(hwnd, SW_SHOW);
    
        // 8.消息循环
        MSG msg;
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
    	return 0;
    }
    
    /*
    9.回调函数
    
    窗口消息处理程序 窗口回调函数:
    
      1.窗口回调函数处理过的消息,必须传回0.
      2.窗口回调不处理的消息,由DefWindowProc来处理.
    */
    
    LRESULT CALLBACK WindowProc(
                                IN  HWND hwnd,
                                IN  UINT uMsg,
                                IN  WPARAM wParam,
                                IN  LPARAM lParam
                                )
    {
        switch(uMsg)
        {
        case WM_DESTROY:
            {
                //DbgPrintf("WM_DESTROY %d %d \r\n",wParam,lParam);
                PostQuitMessage(0);
    
                return 0;
            }
    
        }
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    
    
    

    效果展示

    image

  • 相关阅读:
    浏览器缓存机制
    vim 同时操作多行
    webpack打包性能优化
    测试 IE 浏览器兼容性 VirtualBox + modern.ie
    react-redux 学习笔记
    Redux 学习笔记
    Mac 下抓包工具 Charles 修改特定请求
    PyUsb的使用记录--window中
    Java 通过Jna调用dll路径问题
    OpenJdk14精简jdk运行javaFx样式丢失问题
  • 原文地址:https://www.cnblogs.com/autopwn/p/15545626.html
Copyright © 2020-2023  润新知