• 如果建立的是Win32控制台工程(入口函数是main函数)的话,WinMain函数不能作为入口函数,如果想要解决这个问题的话,可以打开项目属性->链接器->系统->子系统,把子系统对应的“控制台”改为“窗口”。

  • 名词释义:

  • API:应用程序编程接口(Aplication Programma Interface),是一组定义、程序及协议的集合,是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。

  • SDK:软件开发包(Software Development Kit),SDK是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等创建应用软件的开发工具的集合。它可以简单的为某个程序设计语言提供应用程序接口API的一些文件,但也可能包括能与某种嵌入式系统通讯的复杂的硬件。SDK还经常包括示例代码、支持性的技术注解或者其他的为基本参考资料澄清疑点的支持文档。

  • 窗口:包含标题栏、菜单栏、系统菜单、最下化框,最大化框,滚动等,窗口主要分为客户区和非客户区;

  • 句柄:是一个标识符,是用来标识对象或者项目的。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个Windows函数来获得一个句柄,之后其他的Windows函数就可以使用该句柄,以引用相应的对象。在 Windows编程中会用到大量的句柄。在 Windows程序中并不是用物理地址来标识一个内存块、文件、任务或动态装入模块的。相反地,Windows API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。

  • 窗口程序的入口函数:WinMain 控制台窗口应用程序入口函数:main

  • WINAPI:本质是__stdcall,(stdcall调用方式又被称作Pascal调用方式)是C/C++调用约定的一种,意思是函数的参数从右到左推送到栈上,被调用函数在返回之前从堆栈中弹出这些参数;

WINAPI可以看做是函数调用约定,约定了:

  1. 函数的入栈方式——从右往左

  1. 函数调用后,由谁来将堆栈恢复原状

  • WINAPI、CALLBACK、APIENTRY:从右往左入栈,本质都是__stdcall(标准调用方式);

WINAPIV:从右往左入栈,本质是__cdecel;

//转到定义,可以看到:
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define WINAPIV __cdecl
#define APIENTRY WINAPI
  • C++函数调用的几种方式:

  1. stdcall

stdcall调用方式的函数声明为:int __stdcall function(int a,intb);

stdcall的调用方式意味着:

  1. 参数从右往左依次压入堆栈;

  1. 由被调用函数自己来恢复堆栈;

  1. 函数名自动加前导下划线,后面紧跟着一个@,其后紧跟着参数的尺寸。

上面函数翻译成汇编语言将变成:

push b先压入第二个参数

push a再压入第一个参数

call function调用函数

在编译时,此函数的名字翻译成_function@8

  1. cdecl

cdecl调用函数又称为C调用方式,是C语言缺省的调用方式,它的语法为:

int function(int a,int b)//不加修饰符就是C调用方式

int __cdecl function(int a,int b)//明确指定C调用方式

cdecel调用方式决定了:

  1. 参数从右向左依次压入堆栈;

  1. 由调用者恢复堆栈;

  1. 函数名自动加前导下划线。

由于是由调用者来恢复堆栈,因此C调用方式允许函数的参数个数是不固定的,这是C语言的一大特色。

此函数被翻译为:

push b //先压入第二个参数

push a //再压入第一个参数

call function // 调用函数

add esp, 8 //清理堆栈(此内容在汇编中esp寄存器的功能部分有讲)

在编译时,此方式的函数被翻译成:__function

  • 主函数参数:

  • HINSTANCE:应用程序实例句柄类型;

//转到定义,看到本质为结构体指针:
DECLARE_HANDLE(HINSTANCE);
#define DECLARE_HANDLE(HINSTANCE)
struct HINSTANCE__
{
int unused;
};
typedef struct HINSTANCE__* HINSTANCE
  • hInstance :当前应用程序实例句柄;

  • hPreInstance:当前程序的前一个实例句柄,在32和64位机器上已废弃,现在不再使用,值为NULL,在16位机器上使用(任何一个基于GDI的Windows程序以WinMain函数作为入口被系统调用,在Win16中,hPreInstance指向程序的前一个实例句柄,但在Win32中,每一个进程都有一个独立的4G地址空间,从0到2G属于进程私有,对其他进程来说是不可见的。所以在Win32中,hPreInstance总是为NULL);

  • LPSTR:long point string;

typedef CHAR *NPSTR, *LPSTR, PSTR;
//上式表示 CHAR <=> NPSTR <=> LPSTR <=> PSTR
typedef char CHAR;
//LPSTR <=> char*
//LPCSTR <=> const char*
  • lpCmdLine:[in] Pointer to a null-terminated string specifying the command line for the application, excluding the program name. To retrieve the entire command line, use the GetCommandLine function.(指向一个应用程序命令中,除了程序名的null字符结束的字符串。GetCommandLine函数可以返回整个命令行)

lpCmdLine是一个以空终止的字符串,指定传递给应用程序的命令行参数。

  • nCmdShow:窗口显示方式(最大化,最小化,普通,正常显示);

  • MessageBox:Windows编程中经常用到的一个API,作用是弹出一个消息提示框;

int WINAPI MessageBox (
In_opt HWND hWnd,
In_opt LPCTSTR lpText,      //要在消息框中显示的文本
In_opt LPCTSTR lpCaption,   //对话框标题。如果为 NULL(默认值),则使用标题“错误”
In UINT uType       //指定对话框的内容和行为。有关可用不同消息框的列表,请参阅 Windows SDK 文档中的消息框条目。默认值提供一个简单的“确定”按钮。
);

第一个参数:

HWND : 窗口句柄类型(可以理解为窗口的ID)

hWnd : 父窗口句柄,如果没有父窗口,就写NULL

HWND 本质为结构体指针

/*   HWND : 窗口句柄类型(可以理解为窗口的ID)hWnd : 父窗口句柄,如果没有父窗口,就写NULLHWND 本质为结构体指针                  */
DECLARE_HANDLE (HWND);
#define DECLARE_HANDLE(name)
struct HWND__
{int unused;
};     typedef struct HWND__ *HWND
/*LPCTSTR:显示内容*/
//LPCTSTR在Unicode编码下
typedef LPCWSTR PCTSTR, LPCTSTR;          //LPCWSTR <=> PCTSTR <=> LPCTSTR
typedef  CONST WCHAR *LPCWSTR, *PCWSTR;   //CONST WCHAR* <=> LPCWSTR <=> PCWSTR
#define CONST               const         //CONST <=> const
typedef wchar_t WCHAR;                    //wchar_t <=> WCHAR//const wchar_t* <=>  LPCTSTR
//上述内容:LPCTSTR <=> const wchar_t*
/*LPSTR在多字节字符集情况下*/
typedef LPCTSTR PCTSTR, LPCTSTR;           //LPCTSTR  <=> PCTSTR <=> LPCTSTR
typedef  CONST CHAR *LPCWSTR, *PCWSTR;     //CONST CHAR* <=> LPCTSTR <=> PCWSTR
#define CONST const                        //CONST <=> const
typedef char CHAR;                         //char <=> CHAR
//上述内容:LPSTR <=> const char*
  • 实操

1.Hello World!

#include <Windows.h>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine , int nCmdShow)
{int n = MessageBox(NULL, L"Hello World!", L"温馨提示", MB_OK);if (n == IDOK){MessageBox(NULL, L"点了OK", L"提示", MB_OK);}else if (n == IDNO){MessageBox(NULL, L"点了No", L"提示", MB_OK);}else if (n == IDYES){MessageBox(NULL, L"点了Yes", L"提示", MB_OK);}return 0;
}

2.FirstWindow

  • 流程:①设计窗口;②注册窗口;③创建窗口;④显示窗口;⑤更新窗口;⑥消息循环。

  • 图标制作软件:icoFX3-v3.8.1链接:https://u9baoku.lanzoui.com/b01olvqxc 密码:8udj

  • 窗口处理函数:

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//typedef LONG_PTR            LRESULT;/*virtual LRESULT WindowProc(UINT message,        //message:指定要处理的Windows消息WPARAM wParam,       //wParam:提供用于处理的其他信息。参数值取决于消息LPARAM lParam        //lParam:提供用于处理消息的其他信息。参数值取决于消息
);
*/
  • 源代码

#include <Windows.h>
#include "resource.h"//LRESULT:
//typedef LONG_PTR            LRESULT;   long//第一个参数:窗口句柄
//当前窗口的窗口句柄//第二个参数:消息编号   unsigned int//第三个参数:WPARAM     unsigned int
//窗口附加信息//第四个参数:LPARAM     long
//窗口附加信息//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{/*typedef struct tagWNDCLASSW {UINT        style;WNDPROC     lpfnWndProc;int         cbClsExtra;int         cbWndExtra;HINSTANCE   hInstance;HICON       hIcon;HCURSOR     hCursor;HBRUSH      hbrBackground;LPCWSTR     lpszMenuName;LPCWSTR     lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
#ifdef UNICODE
typedef WNDCLASSW WNDCLASS;UINT*///UINT    //typedef unsigned int        UINT;//一、设计窗口类wchar_t szAppClassName[] = L"My_GUI";wchar_t szWindowName[] = L"这是我的第一个Windows程序";//LoadIcon//加载一个图标文件//第一个参数:应用程序实例句柄//如果是系统资源,传递NULL//如果是自定义资源,传递hInstance//第二个参数:资源ID//LoadCursor//加载一个光标文件//第一个参数:应用程序实例句柄//如果是系统资源,传递NULL//如果是自定义资源,传递hInstance//第二个参数:资源IDWNDCLASS wc;wc.style = CS_HREDRAW | CS_VREDRAW;            //窗口类的风格wc.lpfnWndProc = WindowProc;                //窗口处理函数wc.cbClsExtra = 0;                            //窗口类的额外扩展空间大小(字节)wc.cbWndExtra = 0;                            //窗口的额外扩展空间大小(字节)wc.hInstance = hInstance;                    //当前应用程序实例句柄wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LOGO));                            //窗口图标句柄,NULL:没有图标wc.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR));                            //光标图标句柄wc.hbrBackground = CreateSolidBrush(RGB(255,255,255)); //背景画刷句柄, 0-》255,0:最暗;255:表示最亮  白色:RGB(255,255,255)  红色:RGB(255,0,0)wc.lpszMenuName = NULL;                        //菜单名wc.lpszClassName = szAppClassName;            //窗口类型名//二、注册窗口类//ATOM <= > WORD  <=> unsigned short //DWORD  double WORD   //DWORD  <=> unsigned longif (0 == RegisterClass(&wc)){MessageBox(NULL, L"此程序不能运行在Windows NT上", L"温馨提示", MB_OK);return 0;}//三、创建窗口HWND hWnd = CreateWindow(szAppClassName,                            //窗口类型名szWindowName,                            //窗口的标题WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX,//窗口的风格200,                                    //窗口左上角横坐标200,                                    //窗口左上角纵坐标800,                                    //窗口的宽度600,                                    //窗口的高度NULL,                                    //父窗口句柄NULL,                                    //菜单句柄hInstance,                                //应用程序实力句柄NULL                                    //创建窗口需要传递的信息);if (hWnd == NULL){MessageBox(NULL, L"创建窗口失败", L"温馨提示", MB_OK);return 0;}//四、显示窗口ShowWindow(hWnd, SW_SHOW);//五、更新窗口UpdateWindow(hWnd);//六、消息循环/*typedef struct tagMSG {HWND        hwnd;                        //消息发给哪一个窗口的窗口句柄UINT        message;                    //消息编号,WPARAM      wParam;                        //附加信息LPARAM      lParam;                        //附加信息DWORD       time;                        //消息投放到消息队列里面的时间POINT       pt;                            //消息放入消息队列的时候鼠标的坐标
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;*///只要收到了 WM_QUIT消息,函数返回:0MSG msg;while (GetMessage(&msg, NULL, 0, 0)){//将虚拟键消息转为字符消息TranslateMessage(&msg);//将虚拟键消息分发给窗口处理函数DispatchMessage(&msg);}return 0;//程序退出了,结束了
}//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{switch (uMsg){case WM_CLOSE://窗口关闭消息//MessageBox(NULL, L"点了关闭按钮", L"提示", MB_OK);DestroyWindow(hWnd);//销毁窗口break;case WM_DESTROY://窗口销毁消息PostQuitMessage(0); //发出一个退出消息 :WM_QUITbreak;}return DefWindowProc(hWnd, uMsg, wParam, lParam);//操作系统默认处理消息的函数
}//Windows消息机制原理

Windows编程-001相关推荐

  1. 如何使对话框中接收到WM_CHAR消息(Windows编程)

    我们大家都知道,对话框是有的时候捕获不到WM_CHAR消息的.比如,你想使对话框里的Edit控件所键入的全部变为大写.我们毫不犹豫的写到:    #include //Declare the Dial ...

  2. 使用c++进行Windows编程中各种操作文件的方法 【转】

    https://www.zhaokeli.com/article/8232.html 使用c++进行Windows编程中各种操作文件的方法 [转] 来源:赵克立博客 分类: C/C++ 标签:--发布 ...

  3. 【Windows编程】系列第三篇:文本字符输出

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇我们展示了如何使用Windows SDK创建基本控件,本篇来讨论如何输出文本字符. 在使用Win32编程时,我们常常要输 ...

  4. Windows编程一日一练(1)

    首先,编程和旅游是我个人人生两大爱好,所以,每天空闲的时候我喜欢敲敲代码,或者看看别人写的程序,实在是很惬意.今天想看看window编程,争取坚持每日一练.        windows程序主要是由微 ...

  5. Windows 编程

    Delphi 利用Object Pascal 和可视控件库(VCL)对底层的Windows API 进行了完美的封装,所以很少需要使用基础Pascal 语言来建立Windows应用程序,也无需直接调用 ...

  6. 一个物理学家学习Windows编程的感受

    最近学习用Visual C++ 作为平台的Windows 编程,感觉到学习这种编程技术的过程与学习物理的思维差异非常大.最明显的,比如对于物理课本,在学习的时候值得一个字一个词的认真去读,有时候需要读 ...

  7. C++,C++编程,Windows编程,MFC

    编程 我们日常生活中接触到的电子类产品中的应用都是由编程而来 为什么编程,偷懒 我们通过编程驱使(指挥,命令)的是电信号 为什么上面说编程是偷懒,电的发现,给人们带来了便利,人们在各个方面驱使(换成& ...

  8. Windows编程初步(一)

    第一节:安装帮助文档 使用C语言进行Windows开发,必然使用到WindowsSDK.Windows SDK指Windows开发人员工具包,是为使用C语言开发Windows程序所提供的工具集.里面提 ...

  9. 学好Windows编程要看的书籍

    本文是接着前面的学好C++要阅读的书籍而写的,如果想了解C++的学习的话请先看学好C++要阅读的书籍:http://blog.csdn.net/a809146548/article/details/4 ...

最新文章

  1. 【PHP】字符串去空格并将每个单词首字母转换成大写de多种解法
  2. 常见性能问题:慢sql导致响应时间长分析定位
  3. 不同组织物料类别差异列表
  4. cf(聚簇因子)调优,计划调优,SQL改造
  5. 现在学python2还有意义吗_现在学python该学python2还是python3?
  6. Iframe的基础应用——关于Iframe刷页问题的两种方法
  7. 基于JAVA_JSP电子书下载系统
  8. 苹果台式机怎么设置我的电脑计算机,台式苹果电脑自己怎样做系统
  9. 【javaIO流】--->IO流解析
  10. 采购供应链“双璧”姊妹花,一键实现采购流程精细化管理!
  11. “沉浸式”住宿体验——酒店的新瓶,民宿的老酒
  12. 猫哥教你写爬虫 045--协程
  13. 【验证码逆向专栏】某片滑块、点选验证码逆向分析
  14. 吴枫 python小课账号_吴的解释|吴的意思|汉典“吴”字的基本解释
  15. 理解计算机3D图形学中的坐标系变换
  16. KConfig、Makefile详解以及ARM平台Linux内核的编译
  17. kafka是什么?深刻理解kafka
  18. 五万块钱买什么车好_5万元以下新车5万左右买什么车好
  19. SDK is not loaded yet解决方法
  20. 电脑桌面云便签怎么将一个便签分类里内容移动到另一个分类?

热门文章

  1. NVIDIA安培架构下MIG技术分析
  2. 1666_MIT 6.828 JOS隔离机制的大纲
  3. CVE-2020-3535:Cisco Webex Teams windows客户端dll劫持漏洞分析
  4. linux下cc命令,Linux cc 命令 command not found cc 命令详解 cc 命令未找到 cc 命令安装 - CommandNotFound ⚡️ 坑否...
  5. 考完研的人究竟有多无聊,家用路由器也能给折腾成Web服务器
  6. 用python算卦——银钱演算法
  7. 东软python培训班
  8. 交换机与路由技术-32-命名ACL
  9. C2228 “.xxx”的左边必须有类/结构/联合 c++
  10. Office 2010: word目录更新相关问题