Win32 SDK学习笔记3

我为什么选择Win32SDK以及Win32SDK的特点 玩Win32SDK已有一段时间内,从初中的时候就开始了,虽然时间紧,就假期里或插空背着父母玩会,但是两三年下来,收获也是不浅。所以就想着把我学的东西都整理下来,算是纪念吧,如果还能帮助一下别人,也是我的幸运。 初中的时候对计算机感兴趣,学过C语言,对黑窗口厌烦了,就想着做Windows窗口程序,当时还没有研究过C++的高级特性,于是无缘MFC,对C#那种解释性的语言毫无兴趣,至于VB,都 阅读详情

前文复习

1、思考一下,窗口程序中为什么要注册窗口类?

你想创建什么样的窗口呢?那么,创建什么样的窗口呢?创建前,Window系统可不知道你要的是什么类型的窗口啊(比如标题栏上显示什么图标,鼠标形状是什么,窗口背景颜色等等)。这些类型信息应在你创建前事先告诉Window系统。可以采用这种方法:就是我们事先写一份要创建窗口的类型申请表,提交(注册)给Window系统。然后在创建时,可以让Windows按这个申请表来创建你所要的窗口了。也就是说我们还应该先提交一个申请表,申请成功后再根据这个表创建一个窗口。

我们在使用microsoft平台SDK或者MFC编程时,在创建窗口类后都要先用RegisterClass函数来注册窗口类,这个函数需要一个指向窗口类结构的指针。那么RegisterClass这个windows API函数到底做了什么呢,关于这个函数的源码微软是不会给出来的,因为它只是提供一个系统编程接口,网上也找不到相关说明,只是粗略介绍需要将类注册给系统,但从msdn的atom table说明中我们发现这样一段说明。The system uses atom tables that are not directly accessible to applications. However, the application uses these atoms when calling a variety of functions. For example, registered clipboard formats are stored in an internal atom table used by the system. An application adds atoms to this atom table using。答案有了,在我们构造一个窗口类结构后,我们需要将这个类结构指针加入到system atom table 即SAT中,这样系统就可以通过查找这张表来找到用户自定义的窗口类,window预定义的窗口类指针也在SAT中。SAT实际上实现了一种用于查询的映射,atom实际类型是short,即16位数据。只有系统才可直接访问这张表,但在调用某些api函数时,如Registerclass,可以告知系统来存取这张表。当然,还有本地原子表和全局原子表,这些表应用程序是可以直接访问的。

2、窗口句柄和实例句柄的区别和联系

偶理解实例是一个进程,窗口是一个进程的图形界面
实例句抦用来标识一个程序的一个具体的进程,他的值实际上是这个实例被加载到进程空间的地址。

  • 句柄和ID有什么区别?
    什么是“句柄”(handle),handle的本意是把柄,把手的意思。是你与操作系统打交道的东东。举个通俗的例子,比如你考上了大学,入学后,学校(操作系统)会给你一个学生证号。注意,这个号码是学校指定的,你无法自选。有了这个号码(学生证,假设一证多用)享受学校提供的服务:如你就可以去图书馆借书,去食堂吃饭,去教室上课等等。但你不能到食堂里买啤酒,因为学校不允许这种服务。而在计算机中系统提供的服务就是API调用,你有了HANDLE,就可以理直气壮地向系统提出调用API的服务。而指针的权力就大多了,有了指针你可以到处去喝酒,打架,学校(操作系统)管不着,所以句柄和指针的区别在于句柄指针调用系统提供的服务。而句柄虽然是一个能相互区别的号码,但与我们普通的ID号又有区别,普通的ID号是可以由程序员自己定义的,而句柄不行,它是对象生成是系统指定的,是为了区别系统中存在的各个对象,这个句柄不是由程序员符给的。

  • 句柄
    1。句柄,是整个windows编程的基础,一个句柄是指使用的一个唯一的整数值,是指一个四字节长的数值,用于标志应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息。
    2。句柄不是一个指针,程序不能利用它句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。
    3。句柄是windows用来标志应用程序中建立的或是使用的唯一整数,windows使用了大量的句柄来来标志很多对象。

说明:实例——在windows环境下,不但可以运行多个应用程序,还可以运行多个应用程序的多份拷贝,每个拷贝叫做一个实例,并且有不同的实例句柄。一个实例句柄是windows可以单独运行的副本,是唯一可以标志此实例的整数。

窗口消息处理

Windows窗口就是通过消息来与操作系统互动,窗口不能直接与使用者交流,使用者移动鼠标、敲键盘都是通过操作系统与窗口通信的,因此WinMain()函数中的消息循环很重要,没有它窗口便不能工作,而窗口消息处理函数更为重要,也是我们编程的主要对象。

一、消息循环

消息循环共用到3个函数,GetMessage()的返回值一直不为0,直到接受WM_QUIT时才为0(也就是false)。DispatchMessage()是将消息传给窗口消息处理函数。对初学者来说,这3个函数写法比较固定,但不要认为只能这样写。对消息的正确理解是比较关键的,学习一下消息的结构体。

typedef struct {
    HWND hWnd;//接收消息的窗口的句柄
    UINT message; //消息(应用程序只能用低字节,高字节留给系统用)
    WPARAM wParam; //消息的第一个附加消息
    LPARAM lParam; //消息的第二个附加消息
    DWORD time; 
    POINT pt;
}; MSG, *PMSG;

注意:上面消息循环中的三个函数用的消息是这个结构体的类型,而下面要阐述的消息处理函数的参数,用的是结构体中的第2-4元素即message、wParam、lParam。

二、消息处理函数

Windows中消息的种类大致有2种,即系统消息和应用程序消息,消息的前缀也多种多样。不过日常用到的消息大都以“WM_”开头,而且许多消息的wParam和lParam都为0(也就是不使用),一般只有“WM_COMMAND”菜单命令或键盘鼠标的消息才使用wParam和lParam。
Windows中消息虽然很多,但并不是每一消息都要编程处理,我们一般把不需要特别处理的消息交给缺省消息处理函数DefWindowProc(),例子中的default部分便是。另外,有一函数必须处理,也就是关闭窗口消息WM_DESTROY,这时必须调用PostQuitMessage(0)来向操作系统发送一条终止程序的消息。

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitApp(HINSTANCE, LPCSTR);
BOOL InitInstance(HINSTANCE, LPCSTR, int);

//主入口函数
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
                   LPSTR lpsCmdLine, int nCmdShow)
{
    MSG msg;
    char szClassName[] ="DrawRect";  //窗口名

    //注册窗口类
    if (!InitApp(hCurInst, szClassName)) 
        return FALSE;

    //初始化窗口
    if (!InitInstance(hCurInst, szClassName, nCmdShow)) { 
        return FALSE;
    }

    //消息循环
    while (GetMessage(&msg, NULL, NULL, NULL)) { 
        TranslateMessage(&msg);  //消息解释
        DispatchMessage(&msg);   //消息发送
    }

    return (int)msg.wParam;
}

用的最多的消息可能是WM_PAINT,当窗口改变大小、或有别的窗口从这个窗口面前经过,这个窗口中的文字或图案被冲掉,这就必须重新描画。因此,窗口中要显示的文字或图像一般都是在WM_PAINT中实现的。下面我们以在窗口上显示一行字作例子,不过,这时要稍微知道一点GDI(Graphic Device Interface)的知识。

三、GDI的基础知识

要在窗口描画文字或图像,首先要先取得设备文本(Device Contexts)。取设备文本一般有2种方法,BeginPaint()函数和GetDC()函数。描画结束后必须调用EndPaint()函数和ReleaseDC来释放设备文本。后面2章将继续介绍GDI的基础知识。
要在窗口的某个位置描画文字,必须取窗口的有效区域(ClientRect),因为窗口的边框、菜单、工具条、状态条等部分是不能利用的。例如,要在窗口的正中间写一个字,用窗口宽度和高度的一半来取正中位置是不对的,除非这个窗口无任何边框、菜单、工具条、状态条等。正确的方法是先定义一个区域变量(类型为RECT),然后用GetClientRect()函数取出窗口有效区域放入这个变量中。最后,调用DrawText()函数在矩形区输出文字。DrawText()将在下一章细说,所谓区域类型RECT其实就是一个存放矩形块座标的结构体,下面是RECT的原型。

int DrawText(                                  
  HDC hDC,          //设备文本的句柄           
  LPCTSTR lpString, //要输出的字符串           
  int nCount,       //字符串长度               
  LPRECT lpRect,    //要输出的区域             
  UINT uFormat      //输出的格式                       
  );    

typedef struct _RECT {            
      LONG left;      //左边位置  
      LONG top;       //上边位置  
      LONG right;     //右边位置  
      LONG bottom;    //下边位置  
  } RECT, *PRECT;                 

重绘消息处理

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    HDC hdc;//设备文本句柄
    PAINTSTRUCT ps;//窗口客户区结构体
    TCHAR szHello[] = "My first GDI is so easy and cool!";//显示的文字

    switch(message) {
        case WM_PAINT://重绘消息
            hdc = BeginPaint(hWnd, &ps);//开始描画
            RECT rc;//定义客户区变量
            GetClientRect(hWnd, &rc);//获取窗口有效区域
            //显示文字(横向对中|不自动回行|纵向对中)
            DrawText(hdc, szHello, (int)strlen(szHello),&rc,
                      DT_CENTER|DT_SINGLELINE|DT_VCENTER);
            EndPaint(hWnd, &ps);//结束描画
            break;

显示文字窗口完整程序

#include <windows.h>


TCHAR szWindowClass[] = "My first window's name";
TCHAR szTitle[] = "My first window";

ATOM MyRegisterClass(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {
    MSG msg;

    MyRegisterClass(hInstance);

    if ( !InitInstance(hInstance, nShowCmd) ) {
        return FALSE;
    }

    while ( GetMessage(&msg, NULL, 0, 0) ) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance) {
    WNDCLASSEX wc;

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_VREDRAW | CS_HREDRAW;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    wc.hCursor = LoadCursor(hInstance, IDC_SIZEALL);
    wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szWindowClass;
    wc.hIconSm = LoadIcon(wc.hInstance, IDI_APPLICATION);

    return RegisterClassEx(&wc);
}

BOOL InitInstance(HINSTANCE hInstance, int ncmdshow) {
    HWND hWnd;

    hWnd = CreateWindow(szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        400,
        120,
        NULL,
        NULL,
        hInstance,
        NULL);
    if (!hWnd) {
        return FALSE;
    }
    ShowWindow(hWnd, ncmdshow);
    UpdateWindow(hWnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

    HDC hdc;
    PAINTSTRUCT ps;
    TCHAR szHello[] = "My first GDI is so easy and cool!";

    switch(message) {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            RECT rc;
            GetClientRect(hWnd, &rc);
            DrawText(hdc, szHello, (int)strlen(szHello),&rc,
                      DT_CENTER|DT_SINGLELINE|DT_VCENTER);
            EndPaint(hWnd, &ps);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
WIN32SDK自绘Tooltip WIN32SDK自绘Tooltip 支持文字和图片 阅读详情

相关推荐

win32项目,win32控制台,API,SDK,MFC

前段时间学习简单项目开发的时候发现需要设计windows对话框应用程序,于是去学了SDK,但是后来跟着书敲代码的时候又是用了MFC框架,于是来总结下这些概念 win32项目与win32控制台 1.界面 win32控制台项目是在32位Windows命令提示符(即所谓的dos)环境下运行的应用程序,所谓dos界面全称为Disk Operating System,意思是“磁盘操作系统”,就是那个黑

yong_ss的博客 963

Win32汇编--图形操作--GDI原理

Win32汇编--图形操作--GDI原理   Windows是基于图形界面的,所以在Win32编程中,图形操作是最常用的操作。GDI的意义在于将程序对图形界面的操作和硬件设备隔绝开来,在程序中可以将所有的图形设备都看成是虚拟设备,包括视频显示器和打印机等,然后通过GDI函数用同样的方法去操作它们,由Windows负责将函数调用转化成针对具体硬件的操作。只要一个设备提供了和Windows兼容的驱

锄禾日当午 3398

Win32SDK基本 RC资源的使用

本文由优快云用户zuishikonghuan所作,转载请注明出处 一,图标 上一篇博文“[Win32SDK基本] 窗口详解(超详细)"中(地址:http://blog.youkuaiyun.com/zuishikonghuan/article/details/46378475),提到了图标的问题,上一次我是直接使用系统的默认图标了事的,这一回来讲解如何使用自己的图标。 在注册窗口类的时候,

zuishikonghuan的博客 4083

Win32消息处理API---PostMessage

 06、PostMessage功能说明PostMessage将消息投递到进程的消息队列,不会等待进程处理消息完毕就返回,PostMessage所投递的消息会被进程所调用的GetMessage或者PeekMessage函数所检索。PostMessage对消息的投递行为属于异步发送,即发送消息而不必等待消息被处理之后再返回。PostMessage在投递消息时,系统根据hWnd参数来判断所属

mengde666的专栏 9574

[Win32SDK基本]Button Control(3)Group Boxes

上两篇中说了push button和check box这两种按钮,上两篇中还算有点东西说,BM_SETIMAGE 和 BM_SETCHECK 嘛,可是 Group Boxes 我实在是不知道说些什么好了,但好歹也是按钮控件的一种,于是就说说。 MSDN:A group box is a rectangle that surrounds a set of controls, such a

zuishikonghuan的博客 2477

VC win32 Application SDK创建窗口Demo

win32.h#ifndef _X_WIN32_H_#define _X_WIN32_H_BOOL InitApplication(HINSTANCE);BOOL InitInstance(HINSTANCE,int);LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);#endif win32.cpp#include

OYJJ的专栏 4506

Windows 消息列表

下面是用于 PostMessage 和 SendMessage 中 Msg 参数的值的列表. 要找到如何使用特殊消息的更多细节 (例如 WM_VSCROLL), 请在 http://msdn.microsoft.com 或您喜欢的搜索引擎中搜索消息的名称. 同时, 认真学习 消息指南. WM_NULL = 0x00 WM_CREATE = 0x01 WM_DESTROY = 0x02 W

liuyukuan的专栏 1006

VC++ WIN32 sdk实现按钮自绘详解.

  网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说.实例图片:  首先建立一个标准的Win32 Application 工程.选择a simple Win32 Application.然后建立我们的资源文件首先新建一个对话框资源,资源ID改为IDD_MAIN_DLG然后在其上新建一个按钮控件资源ID改为IDC_ODBUTTON,

geniusdot的专栏 1万+

Win32 应用程序的开发本质--MSG

Win32应用程序永远脱离不了MicroSoft.也就意味着Windows 的消息机制永远是Win32应用的根本。        作为一个Windows 开发者对消息机制的理解深度决定了他的开发功底,一切事件因为消息而开始。       所以我今天最想提到的就是MSG。      MSG结构体   在Windows程序中,消息是由MSG结构体来表示的。MSG结构体的定义如下(参见MSDN)

vanileo的专栏 1553

[Win32SDK基本]Edit Control详解

对于Win32窗口控件也说了不少了,今天来说说编辑框 Edit Control控件。 MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/bb775458(v=vs.85).aspx 其实还是子窗口,static那节说的很明白了,就不重复了 ,这个控件的类名是Edit 创建两个edit control: HWN

zuishikonghuan的博客 1万+

[Win32SDK基本]开启UI系统风格

最近太忙了,马上就期末考试了,本来想说说模态窗口来的,但是稿子没写完,所以今天先说说系统风格: 先看看我之前做的一系列程序的运行图片: 开启系统风格之后: 可以发现按钮可以文字图片共存了,同时界面漂亮了很多,这是如何实现的呢? 其实系统风格就是使用win32的控件版本6.0 方法一:直接在cpp里头文件include下面加上这么一行即可: #pragma comment

zuishikonghuan的博客 3438

win32 Message(MSG)消息处理

一般情况下的消息处理如下,TranslateMessage转换virtual-keys消息到characters消息,DispatchMessage调度一个消息给窗口程序。 //getMessage第二个参数为HWND,这里设置为NULL, //如果设置为hwnd,WM_DESTROY消息会响应不到 while(getMessage(&msg,NULL,0,0) { ...

941

[Win32SDK基本] Combo Box

老规矩,先上MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/bb775792(v=vs.85).aspx 其实还是子窗口,static那节说的很明白了,就不重复了 ,这个控件的类名是COMBOBOX Combo Box分为3种: 1。Simple 风格为:CBS_SIMPLE Displays the l

zuishikonghuan的博客 3342

WIN32 SDK 创建窗口实例

在Windows平台做开发都需要了解WIN32的应用程序运行机理,最近也正在学习使用MFC。所以用WIN32 SDK写了一个绘制窗口的简单程序。程序虽然没有什么功能,但是已经展示了WIN32应用程序机理的基本。  #include #include  LRESULT CALLBACK WinProc(  HWND hwnd,        UINT message,      

杜聪聪的博客 1387

从零开始:用Win32 SDK构建MFC风格的Windows程序

控件的使用与自定义是提高用户交互体验的关键步骤。本节将讲解如何创建和使用常用控件,以及如何自定义控件。在某些情况下,标准控件无法满足特定的用户界面需求,这时需要自定义控件。自定义控件需要处理消息,并根据消息绘制和行为。下面的代码展示了如何实现一个简单的自定义控件:// 自定义控件的消息处理函数// 在这里添加绘制代码break;// 其他消息处理...default:return 0;// 创建自定义控件"CustomControlClass", // 自定义控件的类名。

weixin_29155599的博客 1105

基于卷积神经网络的人脸表情识别(JAFFE篇)

1.win10/11操作系统2.python3.7以上3.tensorflow2.4以上版本(2.0其它版本需要微调)4.内存12G,显卡4G以上(没有独显倒是也能跑...)(这个可爱的妹子就是JAFFE数据集中的图片)

小林同学的计算机学习 5913

Win32 SDK利用ListView控件。

Win32 SDK利用ListView控件。 为了使用ListView控件,我们需要初始化公共控件库,我们需要在程序刚刚启动时调用 InitCommonControls() 函数,如果发生链接错误,说明我们没有链接拥有该函数的库文件。它们对应的 头和库 DLL分别为 #include comctl32.lib comctl32.dll  为了使用这个控件 我们就需要知道它的窗口类,利用S

hust_sasuke的专栏 1832

一种解决STM32多串口同时收发的方法

在做项目中,遇到了同时调用串口通信时程序崩溃的问题,在项目中,串口1用作调试串口,串口2用作MQTT通信串口,串口3用作下位机通信串口, 串口1重定向以后,用库函数自带的printf函数打印字符串 串口2使用自己写的u2_printf函数,即va_list这套变参宏定义后使用vsprintf函数打印字符串 串口3刚开始使用串口2一样的打印方式,程序在调试调用到串口3打印函数时直接崩溃,后续将串口3改用dma转存输出,仍然无法正常调用 多次研究以后,采用三个串口都使用重定向后的库函数自带的printf

Zxp0605的博客 8796

我选择了WIN32 ASM和 WIN32 SDK

在兵荒马乱的时代,我选择了WIN32 ASM和 WIN32 SDK,现在IT新技术日新月异。就常用编程语言而言,有c/c++,pascal/object pascal,basic,Forturn,asm,java,c#等等。 操作系统平台有unix/linux,windows系列。编程环境有:java的jvm平台,微软新的.net平台。每个大平台下,还有很多的的方向:如网络,数据库,shell编程

小榕^_^(Littleroy)的专栏 1904

IOPaint模型部署教程

IOPaint是一款功能全面且强大的AI图像处理工具,它不仅免费开源,还由SOTA(State-of-the-Art,即最先进)AI模型驱动,为图像编辑和修复带来了前所未有的便利和高效。以下是对IOPaint的详细介绍:

SJJS_1的博客 1540

10、网络安全工具:Bettercap 与 Web 应用测试工具全解析

本文详细解析了网络安全工具Bettercap及其在中间人攻击和无线攻击中的应用,同时介绍了多种Web应用测试工具,如Amass、Cadaver、Dirb等,并探讨了工具的使用场景、流程、注意事项以及未来发展趋势,为网络安全测试提供了全面的指导。

u0v1w2x3的博客 227

pywin32、win32api、win32gui、win32com、win32con 都是啥?

pywin32、win32api、win32gui、win32com、win32con 名称非常类似,特别容易混淆,今天就用600字给大家区分一下 文章目录pywin32win32guiwin32conwin32apiwin32com记录时间 pywin32 pywin32 主要的作用是供 Python开发者快速调用 Windows API的一个模块库。该模块的另一个作用是是通过Python进行COM编程。 落地场景: 如果你想在Windows操作系统用Python实现自动化工作,pywin32模块经常用到

梦想橡皮擦,专栏100例写作模式先行者,现象级专栏 《Python 爬虫 100 例》作者、《滚雪球学 Python 专栏》原创者 3万+

河洛理数【陈抟】每月月卦推演每日运卦

Step2:每卦中的日爻遇到二十四节气中的当日为节(月初)或气(月中)的时候,所代表的日期需要变更。正常来说,屯卦分别代表初一到初六,但是由于当月初二时立秋节,所以初爻就不能作为初一、而是要作为立秋节开始时(文中还精算到了立秋是从初二的午时开始),如下。说的代表月运的基础卦上进行当月日卦的推演方式。老样子,我们还是按照书中举得例子卦在这边进行一步步的推演,最后做总结。Step1:从月卦爻下一爻开始,自下而上,进行五个爻的爻变,新推演的每个卦代表六天,如下。假设当月月卦是即济卦,月爻在二爻,如图所示(

Daniel专栏 764
上一篇: C++ vector用法初步学习
下一篇: Win32 SDK 学习笔记4
henhaoji_123
博客等级 码龄10年 260粉丝 283原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值