Loading

1_windows历程.md

windows历程

Hello World

#include <windows.h>

int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
    MessageBox(NULL, TEXT("啦啦啦"), TEXT("Hello, World!"), MB_OKCANCEL);
    return 0;
}

UNICODE

使用unicode解决ascii

DBCS编码集

使用TCHAR作为字符集


窗口

/* -------------------------------------------------------------------
                    MyWindows.c -- 基本窗口模型  
                                《Windows 程序设计(SDK)》视频教程                    
--------------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        static TCHAR szAppName[] = TEXT("MyWindows");
        HWND hwnd;
        MSG msg;
        WNDCLASS wndclass;

        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;

        if (!RegisterClass(&wndclass))
        {
                MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
                return 0;
        }

        hwnd = CreateWindow(szAppName, 
                TEXT("鱼C工作室"), 
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT, 
                CW_USEDEFAULT, 
                CW_USEDEFAULT, 
                CW_USEDEFAULT,
                NULL, 
                NULL, 
                hInstance, 
                NULL);
        
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);

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

        return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        switch (message)
        {
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);
                DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); k
                EndPaint(hwnd, &ps);
                return 0;

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}

注意:使用MinGW编译时添加 -mwindows选项

Windows 窗口的诞生过程。

定义窗口类结构(WNDCLASS) -> 注册窗口类(RegisterClass) -> 创建窗口(CreateWindow) -> 显示窗口(ShowWindow) -> 更新窗口(UpdateWindow) -> 消息循环(GetMessage -> TranslateMessage ->DispatchMessage


事件驱动

1571661504808

DispatchMessage将消息传给os,os再调用callback

第001讲:【*】__stdcall,__cdecl,__pascal,__fastcall的区别

【*】标记为非必要掌握内容,可以先收藏,今后某一天你会需要用到的。

__cdecl

__cdecl 是 C Declaration 的缩写,表示 C 语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

__stdcall

__stdcall 是 Standard Call 的缩写,是 C++ 的标准调用方式:所有参数从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是 this 指针。这些堆栈中的参数由被调用的函数在返回后清除,使用的指令是 retnX,X 表示参数占用的字节数,CPU 在 ret 之后自动弹出 X 个字节的堆栈空间,称为自动清栈。函数在编译的时候就必须确定参数个数,并且调用者必须严格的控制参数的生成,不能多,不能少,否则返回后会出错。

__pascal

__pascal 是 Pascal 语言(Delphi)的函数调用方式,也可以在 C/C++ 中使用,参数压栈顺序与前两者相反。返回时的清栈方式与 __stdcall 相同。

__fastcall

__fastcall 是编译器指定的快速调用方式。由于大多数的函数参数个数很少,使用堆栈传递比较费时。因此 __fastcall 通常规定将前两个(或若干个)参数由寄存器传递,其余参数还是通过堆栈传递。不同编译器编译的程序规定的寄存器不同,返回方式和 __stdcall 相当。

__thiscall

__thiscall 是为了解决类成员调用中 this 指针传递而规定的。__thiscall 要求把 this 指针放在特定寄存器中,该寄存器由编译器决定。VC 使用 ecx,Borland 的 C++ 编译器使用 eax。返回方式和 __stdcall 相当。

__fastcall 和 __thiscall 涉及的寄存器由编译器决定,因此不能用作跨编译器的接口。所以 Windows 上的 COM 对象接口都定义为 __stdcall 调用方式。

C 语言中不加说明默认函数为 __cdecl 方式(C中也只能用这种方式),C++ 也一样,但是默认的调用方式可以在 IDE 环境中设置。

例子:test1(par1, par2, par3);

img


[扩展阅读] 第003讲:大写标识符的含义

在 Winodows 的定义中包含着许多大写标识符,这些标识符有很多都是以两个或三个字母作为前缀,且其后紧跟一个下划线:

CS_HREDRAW DT_VCENTER SND_FILENAME
CS_VREDRAW IDC_ARROW WM_CREATE
CW_USEDEFAULT IDI_APPLICATION WM_DESTROY
DT_CENTER MB_ICONERROR WM_PAINT
DT_SINGLELINE SND_ASYNC WS_OVERLAPPEDWINDOW

这些标识符其实都是宏定义,前缀标明该常量所属的一般类别,含义如下表:

前缀 含义
CS 类风格选项(ClassStyle)
CW 创建窗口选项(CreateWindow)
DT 文本绘制选项(DrawText)
IDI 图标的 ID 号(IDIcon)
IDC 光标的 ID 号(IDCursor)
MB 消息框选项(MessageBox)
SND 声音选项(Sound)
WM 窗口消息(WindowsMessage)
WS 窗口风格(WindowStyles)

WM_PAINT,WM_TIMER , WM_QUIT 这三个消息属于特例,操作系统会把它们时刻放在消息队列的最后

posted @ 2022-05-27 14:11  nsfoxer  阅读(21)  评论(0编辑  收藏  举报