zoukankan      html  css  js  c++  java
  • Windows SDK 实现不规则窗口介绍

    不规则窗口在程序界面设计中能提供非常好的用户体验,以下是我程序运行时的效果图:

    Windows SDK 实现不规则窗口

    以下是代码,注意需要修改一些简单的位置,如资源ID,项目的头文件等,这些是根据你创建的win32程序的项目名改变的,我的项目名为RgnWindow。

    1 // RgnWindow.cpp : Defines the entry point for the application.
    2 //
    3  
    4 #include "stdafx.h"
    5 #include "RgnWindow.h"
    6 #include <comdef.h>
    7  
    8  
    9 #define ULONG_PTR ULONG
    10 #include <gdiplus.h>
    11 using namespace Gdiplus;
    12 #pragma comment(lib, "gdiplus.lib") //注意,要保证vc路径的lib中,能够找到这个文件
    13  
    14 #define MAX_LOADSTRING 100
    15  
    16 // Global Variables:
    17 HINSTANCE hInst; // current instance
    18 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
    19 TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
    20 GdiplusStartupInput m_gdiplusStartupInput;
    21 ULONG_PTR m_pGdiToken;
    22 HWND g_hWnd = 0;
    23 Image *g_pImageBack=0;
    24 //透明度颜色混合选项
    25 BLENDFUNCTION g_Blend;
    26 //背景图的宽度和高度
    27 int g_BakWidth, g_BakHeight;
    28  
    29 // Forward declarations of functions included in this code module:
    30 ATOM MyRegisterClass(HINSTANCE hInstance);
    31 BOOL InitInstance(HINSTANCE, int);
    32 BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR, Image * & pImg);
    33 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    34 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
    35 void Update();
    36  
    37  
    38 int APIENTRY _tWinMain(HINSTANCE hInstance,
    39 HINSTANCE hPrevInstance,
    40 LPTSTR lpCmdLine,
    41 int nCmdShow)
    42 {
    43 GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);
    44  
    45 UNREFERENCED_PARAMETER(hPrevInstance);
    46 UNREFERENCED_PARAMETER(lpCmdLine);
    47  
    48 // TODO: Place code here.
    49 MSG msg;
    50 HACCEL hAccelTable;
    51  
    52 // Initialize global strings
    53 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    54 LoadString(hInstance, IDC_RGNWINDOW, szWindowClass, MAX_LOADSTRING);
    55 MyRegisterClass(hInstance);
    56  
    57 // Perform application initialization:
    58 if (!InitInstance (hInstance, nCmdShow))
    59 {
    60 return FALSE;
    61 }
    62  
    63 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_RGNWINDOW));
    64  
    65 // Main message loop:
    66 while (GetMessage(&msg, NULL, 0, 0))
    67 {
    68 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    69 {
    70 TranslateMessage(&msg);
    71 DispatchMessage(&msg);
    72 }
    73 }
    74 GdiplusShutdown(m_pGdiToken);
    75 return (int) msg.wParam;
    76 }
    77  
    78  
    79  
    80 //
    81 // FUNCTION: MyRegisterClass()
    82 //
    83 // PURPOSE: Registers the window class.
    84 //
    85 // COMMENTS:
    86 //
    87 // This function and its usage are only necessary if you want this code
    88 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
    89 // function that was added to Windows 95. It is important to call this function
    90 // so that the application will get 'well formed' small icons associated
    91 // with it.
    92 //
    93 ATOM MyRegisterClass(HINSTANCE hInstance)
    94 {
    95 WNDCLASSEX wcex;
    96  
    97 wcex.cbSize = sizeof(WNDCLASSEX);
    98  
    99 wcex.style = CS_HREDRAW | CS_VREDRAW;
    100 wcex.lpfnWndProc = WndProc;
    101 wcex.cbClsExtra = 0;
    102 wcex.cbWndExtra = 0;
    103 wcex.hInstance = hInstance;
    104 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDC_RGNWINDOW));
    105 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    106 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    107 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_RGNWINDOW);
    108 wcex.lpszClassName = szWindowClass;
    109 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    110  
    111 return RegisterClassEx(&wcex);
    112 }
    113  
    114 //
    115 // FUNCTION: InitInstance(HINSTANCE, int)
    116 //
    117 // PURPOSE: Saves instance handle and creates main window
    118 //
    119 // COMMENTS:
    120 //
    121 // In this function, we save the instance handle in a global variable and
    122 // create and display the main program window.
    123 //
    124 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    125 {
    126 HWND hWnd;
    127  
    128 hInst = hInstance; // Store instance handle in our global variable
    129  
    130 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    131 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    132  
    133 //hWnd=CreateWindowEx(WS_EX_TOPMOST|WS_EX_LAYERED|WS_EX_TOOLWINDOW, szWindowClass,NULL,WS_POPUP|WS_SYSMENU,
    134 // 0,0,300,400,NULL,NULL,hInstance,NULL);
    135  
    136 if (!hWnd)
    137 {
    138 return FALSE;
    139 }
    140 //初始化
    141 g_Blend.SourceConstantAlpha = int(0 * 2.55);//1~255
    142 g_Blend.BlendOp=0; //theonlyBlendOpdefinedinWindows2000
    143 g_Blend.BlendFlags=0; //nothingelseisspecial...
    144 g_Blend.AlphaFormat=1; //...
    145 g_Blend.SourceConstantAlpha=255;//AC_SRC_ALPHA
    146  
    147 DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
    148 //设置成工具窗口,无标题栏
    149 SetWindowLong(hWnd, GWL_STYLE, dwExStyle ^ WS_EX_TOOLWINDOW);
    150 //设置成层次窗口
    151 dwExStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
    152 //if((dwExStyle & WS_EX_LAYERED) != WS_EX_LAYERED)
    153 // SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle|WS_EX_TOPMOST|WS_EX_LAYERED);
    154  
    155 //加载图像
    156 //ImageFromIDResource(IDR_CLOCK, L"PNG", g_pImageBack);
    157 g_pImageBack = Image::FromFile(_T("D://launcher//bx.png"));
    158 ImageType t = g_pImageBack->GetType();
    159  
    160 //bkImg.FromFile();
    161 g_BakWidth = g_pImageBack->GetWidth();
    162 g_BakHeight = g_pImageBack->GetHeight();
    163  
    164  
    165 g_hWnd=hWnd;
    166  
    167  
    168 //::SetWindowPos(g_hWnd, HWND_TOPMOST,0,0,g_BakWidth,g_BakHeight,SWP_NOSIZE|SWP_NOMOVE);
    169  
    170 ShowWindow(hWnd, nCmdShow);
    171 UpdateWindow(hWnd);
    172 Update();
    173  
    174 return TRUE;
    175 }
    176  
    177 //
    178 // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    179 //
    180 // PURPOSE: Processes messages for the main window.
    181 //
    182 // WM_COMMAND - process the application menu
    183 // WM_PAINT - Paint the main window
    184 // WM_DESTROY - post a quit message and return
    185 //
    186 //
    187 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    188 {
    189 int wmId, wmEvent;
    190 PAINTSTRUCT ps;
    191 HDC hdc;
    192  
    193  
    194 switch (message)
    195 {
    196 case WM_COMMAND:
    197 wmId = LOWORD(wParam);
    198 wmEvent = HIWORD(wParam);
    199 // Parse the menu selections:
    200 switch (wmId)
    201 {
    202 case IDM_ABOUT:
    203 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    204 break;
    205 case IDM_EXIT:
    206 DestroyWindow(hWnd);
    207 break;
    208  
    209 default:
    210 return DefWindowProc(hWnd, message, wParam, lParam);
    211 }
    212 break;
    213 case WM_PAINT:
    214 hdc = BeginPaint(hWnd, &ps);
    215 // TODO: Add any drawing code here...
    216 Update();
    217 EndPaint(hWnd, &ps);
    218 break;
    219 case WM_DESTROY:
    220 PostQuitMessage(0);
    221 break;
    222 case WM_LBUTTONDOWN:
    223 //禁止显示移动矩形窗体框
    224 ::SystemParametersInfo(SPI_SETDRAGFULLWINDOWS,TRUE,NULL,0);
    225 //非标题栏移动整个窗口
    226 ::SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
    227 break;
    228 default:
    229 return DefWindowProc(hWnd, message, wParam, lParam);
    230 }
    231 return 0;
    232 }
    233  
    234 // Message handler for about box.
    235 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    236 {
    237 UNREFERENCED_PARAMETER(lParam);
    238 switch (message)
    239 {
    240 case WM_INITDIALOG:
    241 return (INT_PTR)TRUE;
    242  
    243 case WM_COMMAND:
    244 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    245 {
    246 EndDialog(hDlg, LOWORD(wParam));
    247 return (INT_PTR)TRUE;
    248 }
    249 break;
    250 }
    251 return (INT_PTR)FALSE;
    252 }
    253  
    254  
    255 BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR, Image * & pImg)
    256 {
    257 HINSTANCE hInst = hInst;//GetResourceInstance();
    258 HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
    259 if (!hRsrc)
    260 return FALSE;
    261 // load resource into memory
    262 DWORD len = SizeofResource(hInst, hRsrc);
    263 BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
    264 if (!lpRsrc)
    265 return FALSE;
    266 // Allocate global memory on which to create stream
    267 HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
    268 BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
    269 memcpy(pmem,lpRsrc,len);
    270 IStream* pstm;
    271 CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
    272 // load from stream
    273 pImg=Gdiplus::Image::FromStream(pstm);
    274 // free/release stuff
    275 GlobalUnlock(m_hMem);
    276 pstm->Release();
    277 FreeResource(lpRsrc);
    278 return TRUE;
    279 }
    280  
    281  
    282 void Update()
    283 {
    284 HDC hdcTemp= ::GetDC(g_hWnd);
    285 HDC hdcMemory=CreateCompatibleDC(hdcTemp);
    286 HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp, g_BakWidth, g_BakHeight);
    287 SelectObject(hdcMemory, hBitMap);
    288  
    289 HDC hdcScreen=::GetDC (g_hWnd);
    290 RECT rct;
    291 ::GetWindowRect(g_hWnd, &rct);
    292 POINT ptWinPos={rct.left,rct.top};
    293 Graphics graph(hdcMemory);
    294  
    295 Point points[] = { Point(0, 0),
    296 Point(g_BakWidth, 0),
    297 Point(0, g_BakHeight)
    298 };
    299  
    300 graph.DrawImage(g_pImageBack, points, 3);
    301  
    302 POINT ptDst;
    303 ptDst.x = rct.left;
    304 ptDst.y = rct.top;
    305 SIZE size={g_BakWidth, g_BakHeight};
    306  
    307 POINT pt;
    308 pt.x = 0;
    309 pt.y = 0;
    310  
    311 //设置成层次窗口
    312 DWORD dwExStyle = GetWindowLong(g_hWnd,GWL_EXSTYLE);
    313 if((dwExStyle & WS_EX_LAYERED) != WS_EX_LAYERED)
    314 {//WS_EX_LAYERED是0x00080000
    315 SetWindowLong(g_hWnd, GWL_EXSTYLE,dwExStyle^WS_EX_LAYERED);
    316 }
    317  
    318 //更新窗口
    319 if (!UpdateLayeredWindow( g_hWnd, hdcScreen, &ptWinPos,
    320 &size, hdcMemory, &pt, 0, &g_Blend, 2))
    321 {
    322 DWORD dwError = ::GetLastError();
    323 printf("failed");
    324 }
    325 //释放资源
    326 graph.ReleaseHDC(hdcMemory);
    327 ::DeleteObject(hBitMap);
    328 ::DeleteDC(hdcMemory);;
    329 ::ReleaseDC(g_hWnd, hdcTemp);
    330 ::ReleaseDC(g_hWnd, hdcScreen);
    331 }

    以上介绍的就是Windows SDK 实现不规则窗口,希望对你有所帮助。

  • 相关阅读:
    java获取客户端用户真实ip
    electron制作上位机软件篇(三)启动项目并进行打包
    electron制作上位机软件篇(二)使用serialport进行串口通信
    electron制作上位机软件篇(一):编译安装serialport
    STM32学习篇-蜂鸣器
    STM32学习篇-跑马灯
    日志级别的选择:Debug、Info、Warn、Error还是Fatal
    常用的正则验证
    kindEditor富文本编辑器
    表单验证jq.validate.js
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/5347656.html
Copyright © 2011-2022 走看看