• 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 这三个消息属于特例,操作系统会把它们时刻放在消息队列的最后

  • 相关阅读:
    Java集合框架--List去重
    solr管理集合
    关于unix环境高级编程、Linux程序设计两部书浅谈
    ubuntu17.10安装lnmp安装包的核心问题-gcc版本、g++版本
    手机谷歌浏览器简洁处理方法
    Ubuntu当状态栏网络图标隐藏的解决方法汇总
    Ubuntu创建WiFi:16.0.4
    关于virtual box 虚拟机使用
    关于json转义中文
    xp 允许序列号
  • 原文地址:https://www.cnblogs.com/nsfoxer/p/14353885.html
Copyright © 2020-2023  润新知