• win32 窗体开发主要流程


    目录

    窗体设计
    回调函数设计
    总体开发流程
    透明窗口编写

    (本章节中例子都是用 VS2005 编译调试的)


    窗体设计

    窗体设计和消息循环设计流图: 

    代码示例:

    //设计窗口
    WNDCLASS wndclass;
    
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);
    wndclass.hInstance=hInstance;
    wndclass.lpfnWndProc=textprom;
    wndclass.lpszClassName="text";
    wndclass.lpszMenuName=NULL;
    wndclass.style=CS_HREDRAW | CS_VREDRAW;
    
    
    //注册窗口类
    if(!RegisterClass(&wndclass))
    {
        MessageBox(NULL,"create windows error!","error",MB_OK | MB_ICONSTOP);
    }
    
    
    //创建窗口
    HWND hwnd=CreateWindow("text","hellow world",WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU,CW_USEDEFAULT,CW_USEDEFAULT,
            CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
    
    
    //显示更新窗口
    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd);
    
    
    //消息循环
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    回调函数设计

    设计流图:

    设计大致模型:

    LRESULT CALLBACK WindowProc(
      HWND hwnd,     // handle to window
      UINT uMsg,     // message identifier
      WPARAM wParam, // first message parameter
      LPARAM lParam   // second message parameter
    )
    {
        ……
        switch(uMsg)
        {
        case ‥ : ……;
              break;
        ……
        case WM_DESTROY:  PostQuitMessage(0);//在消息队列尾部插入一个WM_QUIT消息
                 break;
        default: return DefWindowProc(hwnd,uMsg,wParam,lParam);
        }
        ……
        return 0;
    }

    注意:

    1. 必须把所有不处理的消息交给 DefWindowPro 函数处理,也要把它的返回值返回给 windows 否则 windows 就失去了与应用程序通信的途径也就是说不能在控制窗口的行为
    2. WM_DESTROY 是窗口函数必须处理的消息,因为在窗体销毁的时候并不会主动向程序发送一个 WM_QUIT 这个消息,所以我们的窗体即使销毁了程序依旧还在消息循环中,为了达到在销毁窗体时候并且退出消息循环我们应用处理这个WM_DESTROY 这个消息,在程序接收到这个消息时候向消息队列发一个 WM_QUIT 消息来退出消息循环
    3. WM_CLOSE 默认由 DefWindowPro 函数处理,它会调用 DestroyWindow 函数销毁窗口
    4. WM_CREATE 为 WndProc 第一处理的信息
    5. 在视窗大小改变时,会发 WM_SIZE 这个消息且在 lParam 中 LOWORD(lParam) 中为窗口横坐标 HIWORD(lParam) 中为窗口纵坐标
    6. 回调函数的参数与 MSG 结构的前四位成员相同

    总体开发流程

    程序样例

    View Code
    #include<windows.h>
    #include"resource.h"
    #include<string.h>
    
    LRESULT CALLBACK textprom(
      HWND hwnd,      // handle to window
      UINT uMsg,      // message identifier
      WPARAM wParam,  // first message parameter
      LPARAM lParam   // second message parameter
    );
    
    
    int WINAPI WinMain(  HINSTANCE hInstance,  // handle to current instance
      HINSTANCE hPrevInstance,  // handle to previous instance
      LPSTR lpCmdLine,      // pointer to command line
      int nCmdShow          // show state of window
      )
    {
        WNDCLASS wndclass;
    
        wndclass.cbClsExtra=0;
        wndclass.cbWndExtra=0;
        wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
        wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
        wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);
        wndclass.hInstance=hInstance;
        wndclass.lpfnWndProc=textprom;
        wndclass.lpszClassName="text";
        wndclass.lpszMenuName=NULL;
        wndclass.style=CS_HREDRAW | CS_VREDRAW;
    
    
        if(!RegisterClass(&wndclass))
        {
            MessageBox(NULL,"create windows error!","error",MB_OK | MB_ICONSTOP);
        }
    
    
        HWND hwnd=CreateWindow("text","hellow world",WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU,CW_USEDEFAULT,CW_USEDEFAULT,
            CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
    
    
    
        ShowWindow(hwnd,nCmdShow);
        UpdateWindow(hwnd);
    
    
        MSG msg;
        while(GetMessage(&msg,NULL,0,0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return msg.wParam;
    }
    
    
    
    LRESULT CALLBACK textprom(
      HWND hwnd,      // handle to window
      UINT uMsg,      // message identifier
      WPARAM wParam,  // first message parameter
      LPARAM lParam   // second message parameter
    )
    {
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
    
        switch(uMsg)
        {
        case WM_PAINT:
            hdc=BeginPaint(hwnd,&ps);
            GetClientRect(hwnd,&rect);
            DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect,
                DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(hwnd,&ps);
            break;
        case WM_RBUTTONDOWN:
            hdc=GetDC(hwnd);
            TextOut(hdc,0,0,"success",strlen("success"));
            ReleaseDC(hwnd,hdc);    
            break;
        case WM_RBUTTONUP:
            GetClientRect(hwnd,&rect);
            InvalidateRect(hwnd,&rect,true);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            ;
        }
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }

     示例图片


    透明窗口编写

    步骤:

    • 调用 SetWindowLong 设置窗口属性,把窗口设置为具有GWL_EXSTYLE扩展的窗口风格的窗口(可以用SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE) | WS_EX_LAYERED))
    • 调用SetLayeredWindowAttributes设置窗口透明度

    流程图如下:

    函数 SetLayeredWindowAttributes 说明:

    • 函数原型:
        BOOL SetLayeredWindowAttributes(
          HWND hwnd, // handle to the layered window 透明窗体的句柄
          COLORREF crKey, // specifies the color key 颜色值,可以用RGB(r,g,b)来指定
          BYTE bAlpha, // value for the blend function 透明度,取值范围是[0,255]
          DWORD dwFlags // action 透明方式,
        );
    • dwFlags说明:
      • 当取值为LWA_ALPHA = 0x2 (值为2) 时,crKey参数无效,bAlpha参数有效;
      • 当取值为LWA_COLORKEY = 0x1 (值为1) 时,bAlpha参数无效,而窗体中的所有颜色为crKey的地方将变为透明
      • 也可以取两个值的组合:LWA_ALPHA Or LWA_COLORKEY.这样crKey的地方将变为全透明,而其它地方根据bAlpha参数确定透明度
    • 要求:  要使使窗体拥有透明效果,首先要有 WS_EX_LAYERED 扩展属性(可以调用 SetWindowLong 函数,设置窗体类具有扩展属性属性例如 SetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE, WS_EX_LAYERED) ;)

    窗体半透明控件不透明方法:

    也是使用 SetLayeredWindowAttributes,不同的是,他还用了另一 API 函数 SetParent,基本思路是将某个容器控件用 SetParent 另外指定一个父窗口,这样控件和主窗体就可以分别使用 SetLayeredWindowAttributes 函数,控制透明方式,以迅雷的悬浮窗而言就是,将主窗体以窗体透明的方式 (LWA_ALPHA 标志) 半透明,控件以指定颜色的方式.(LWA_COLORKEY标志) 镂空特定颜色透明,但是由于控件指定了其他的父窗口,因此会有一个不主动跟随窗体移动和显示层次(窗体会覆盖控件)的问题,这些都需要手动控制,实际上就是等于创建两个窗体使用不同的透明方式,然后叠加在一起

    window xp 如何是窗口透明

    1 HINSTANCE hInst = LoadLibrary("User32.DLL");
    2 ModifyStyleEx(0,0x00080000);
    3 typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD); 
    4 MYFUNC fun = NULL;
    5 fun=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
    6 if(fun)    {  fun(this->GetSafeHwnd(),RGB(255,255,0),0,1);  }
    7 FreeLibrary(hInst); 
  • 相关阅读:
    年入50万的众生相
    【史上最全面经】银行类
    Dubbo背景和简介
    剑指Offer66题的总结、目录
    如何写一份更好的简历
    Linux命令 file
    Linux命令 umask
    Linux perm
    Linux 命令 which whereis locate find
    Linux命令 diff cmp patch
  • 原文地址:https://www.cnblogs.com/kzang/p/2709349.html
Copyright © 2020-2023  润新知