-------------------------------------------------- ------------------------------ Overview In the eighth Win32ASM tutorials, the message box, dialog, Menu, resource, gdi, etc. New content, write a comprehensive article. The example of this article is a complex shape window. The shape of the window is automatically calculated according to the bitmap, which is the technology used in the small alarm clock I have written (everyone can go to my software release to download a look. Because the most example of the special shape window seen on the Internet is the most painted shape, or several squares and elliptical combination, no article points out how to draw such a model such as "Tang Duck" window. The algorithm used herein can automatically calculate the window shape according to the shape of the bitmap. In the source program, many code is mentioned earlier, mainly with the following parts: first establish a standard window. (Reference Window section) Setting the window as a special shape. (See the program analysis below) Update the window of the window in the WM_PAINT message of the window. (Reference graphical interface) Since the window does not have a title bar, a menu pops up when you right click on the window. (Reference Menu Heet) There is a "About this Program" item in the menu, there is a super knot text. (Reference window subclassification) There is a special API in Windows to achieve a special shape window, step is to build a region (Region), and region can be merged, so that several simple areas can be used to combine a complex area The API of the area, the establishment, merge area, and settings window has the following: CreateRectrgn (Left, Top, Right, Bottom) - Creating a rectangular area CreatellipticRGN (Left, Top, Right, Bottom) - Create an ellipse area CreatePolygonRgn (LPPoints , NumberOfPoints, Mode) - Create a polygonal area, these APIs return Combinergn (HDEST, HSOURCE1, HSOURE2, Combinemode) - Merge Area SetWindowRGN (HWND, HRGN, BREDRAW) - The method of the program is a scanning bit map Point, press in the row setting area and then merge into the total area.
Source program - assembly source file; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Folding code; >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DEBUG = 0; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder (Luo Yunbin's programming park); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Demonstration procedure Ver 1.0; you can automatically set the shape of the window according to the bitmap.
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folding >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >; Include data; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> include windows.incinclude user32.incinclude kernel32.incinclude comctl32.incinclude comdlg32.incinclude shell32.incinclude gdi32.incincludelib user32.libincludelib kernel32. LibincludeLiB ComctL32.libinCludelib comdlg32.libincludelib shell32.libincludelib gdi32.lib; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>
************* EQU data ****************************************** Iconidc_handle EQU 2; CURSOR; ************** * *********************************** ********** DLG_ABOUT EQU 1200; Dialog - Aboutid_about_ok EQU 1201ID_EMAIL EQU 1202ID_HomePage EQU 1203; ************** * ***************** ************************ IDM_MAIN EQU 2000IDM_ABOUT EQU 2001IDM_EXIT EQU 2002; ************** EQU data ** ******************************** IDB_0 EQU 3000; Bitmap; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> but BACKGROUND BITMAPHDCBACK DD?; ************************************************************************ *******. DataSzclassName DB 'ShapeWindow', 0; >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>
.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, \ ************************; Setting the window shape is the shape of the BMP graphic; parameter: window handle, BMP graphics handle; input BMP graphics requirements: 0, 0 color is the background color; *************************************************** ************************ _ SETWORDOWSHAPE PROC HWND: DWORD, HBITMAP: DWORDLOCAL @HDC: DWORD, @ HBMPDC: DWordLocal @stps: PaintstructLocal @stRect: RECTlocal @stBmp: BITMAPlocal @dwX: DWORD, @ dwY: DWORD, @ dwStartX: DWORDlocal @hRgn: DWORD, @ hRgnTemp: DWORDlocal @rgbBack: DWORDinvoke GetObject, hBitMap, sizeof BITMAP, addr @stBmpinvoke GetWindowRect, hWnd, addr @stRectinvoke ShowWindow , hWnd, SW_HIDEinvoke MoveWindow, hWnd, @ stRect.left, @ stRect.top, / @ stBmp.bmWidth, @ stBmp.bmHeight, FALSEinvoke GetDC, hWndmov @ hDC, eaxinvoke CreateCompatibleDC, @ hDCmov @ hBmpDC, eaxinvoke SelectObject, @ hBmpDC, Hbitmap; ************** Calculated window shape ************************************************** ********* Invoke getpixel, @ hbmpdc, 0,0mov @ rgbback, EaxInvoke CreateRectRGN, 0, 0, 0, 0mov @ hrgn, Eaxmov @ dwy, 0.While Truemov @ dwx, 0mov @ dwstartx, - 1.While Trueinvoke getpixel, @ hbmpdc, @ dwx, @ dwy.if @dwstartx == -1.if eax! = @RGBBackmov Eax, @ dwxmov @ dwstartx, eax.endif.else.if eax == @RGBBackvoke CreateRectrGN, @ dwstartx, @ dwY, @ dwX, ecxinvoke CombineRgn, @ hRgn, @ hRgn, eax, RGN_ORmov @ dwStartX, -1.elsemov eax, @ dwX.if eax == @ stBmp.bmWidthinc eaxmov ecx, @ dwYinc ecxinvoke CreateRectRgn, @ dwStartX, @ dwY , EAX, ECXINVOKE Combinergn, @ hrgn, @ hrgn, eax, rgn_ormov @ dwstartx, -1.endif.endif.EndifIfincinc @dwxmov Eax, @ dwx.break .if eax> @ stbmp.bmwidth.Endwinc @
Dwymov Eax, @ dwy.break .if Eax> @ stbmp.bmheight.ndwinvoke setwindowrgn, hwnd, @ hrgn, true; *********************** **************************************************** Invoke Bitblt, @ HDC, 0,0, @ stBmp.bmWidth, @ stBmp.bmHeight, / @ hBmpDC, 0,0, SRCCOPYinvoke DeleteDC, @ hBmpDCinvoke ReleaseDC, hWnd, @ hDCinvoke InvalidateRect, hWnd, NULL, -1ret_SetWindowShape endp; ******* *********************************************************** ***********; Move the window to the middle of the screen; parameter: window handle; ************************ **************************************************** _ CenterWindow Proc HWnd: DWordLocal @stRectDesktop: RECT, @ stRectWin: RECTlocal @dwWidth: DWORD, @ dwHeight: DWORDinvoke GetWindowRect, hWnd, addr @stRectWininvoke GetDesktopWindowmov ebx, eaxinvoke GetWindowRect, ebx, addr @stRectDeskTopmov eax, @ stRectWin.bottomsub eax, @ stRectWin.topmov @ dwHeight, eaxmov eax , @ stRectWin.rightsub eax, @ stRectWin.leftmov @ dwWidth, eaxmov ebx, @ stRectDeskTop.bottomsub ebx, @ dwHeightshr ebx, 1mov ecx, @ stRectDeskTop.rightsub ecx, @ dwWidthshr ecx, 1invoke MoveWindow, hWnd, ecx, ebx, @ DwWidth, @ dwhe IgHT, FALSERET_CENTERWINDOW ENDP; ************************************************************************************ *********************** Include About.asm; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>
>>>>>>>> START: Call_WinMainInvoke EXITPROCESS, NULL; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>> _ WinMain proclocal @stWcMain: WNDCLASSEXlocal @stMsg: MSGinvoke InitCommonControlsinvoke GetModuleHandle, NULLmov hInstance, eaxinvoke LoadIcon, hInstance, IDI_MAINmov hIcon, eaxinvoke LoadMenu, hInstance, IDM_MAINinvoke GetSubMenu, eax, 0; PopUp menu to use child Menu MOV HMENU, EAX; ***************************************************************************************************************************************************************************************************************************************************************************************** *************** invoke LoadCursor, 0, IDC_ARROWmov @ stWcMain.hCursor, eaxmov @ stWcMain.cbSize, sizeof WNDCLASSEXmov @ stWcMain.hIconSm, 0mov @ stWcMain.style, CS_HREDRAW or CS_VREDRAWmov @stWcMain .lpfnWndProc, offset WndMainProcmov @ stWcMain.cbClsExtra, 0mov @ stWcMain.cbWndExtra, 0mov eax, hInstancemov @ stWcMain.hInstance, eaxmov @ stWcMain.hIcon, 0mov @ stWcMain.hbrBackground, COLOR_WINDOW 1mov @ stWcMain.lpszClassName, offset szClassNamemov @stWcMain. LpszMenuname, 0invoke registerclassex, addr @stwcmain; ******* ********** Establish an output window ****************************************************** ****; Property: There is no title bar, not displayed in the taskbar;
*********************************************************** ***************** Invoke CreateWindowex, WS_EX_TOOLWINDOW, / OFFSET SZCLASSNAME, NULL, / WS_POPUP or WS_SYSMENU, / 0, 0, 1, 1, / NULL, NULL, HINSTANCE, Nullinvoke showWindow, hwinmain, sw_shownormalinvoke updateWindow, hwinmain; ***************************************************** *******************. While TrueInvoke GetMuss, AddR @ Stmsg, Null, 0, 0.Break .if Eax == 0invoke TranslateMessage, AddR @stmsginvoke DispatchMessage, Addr @ stmsg.Endwret_winmain endp; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> WNDPROC PROC USES EBX EDI ESI, / HWND: DWORD, UMSG: DWORD, WPARAM: DWORD, LPARAM: DWORDLOCAL @stpos: PAINTLOCAL @stps: Paintstruct, @ hdc: dwordmov Eax, umsg.if eax == wm_createmov Eax, hwndmov hwinmain, eaxcall _init; ******************************** ******************************************. Elseif EAX == WM_PAINTINVOKE BEGINT, HWND, ADDR @stpsmov @ HDC, Eaxmov Eax, @ stps.rcpaint.rightsub eax, @ stps.rcpaint.LEFTMOV ECX, @ stps.rcpaint.bottomsub ECX, @ stps.rcpaint.topin Voke Bitblt, @ hdc, @ stps.rcpaint.Top, Eax, ECX, / HDCBACK, @ stps.rcpaint.top, @ stps.rcpaint.top, srccopyInvoke endpaint, hwnd, addr @stps; *********************************************************** ************; because there is no menu, the following code is used to pop up the popup menu when the right button is pressed; ************** *********************************************************** ***. Elseif Eax == WM_RBUTTONDOWN.IF WPARAM == MK_RBUTTONIKE GETCURSORPOS, ADDR @
STPOSINVOKE TRACKPOPUPMENU, HMENU, TPM_LEFTALIGN, @ stpos.x, @ stpos.y, null, hwnd, null.endif; ********************************** ********************************; because there is no title bar, below The code is used to move the window when the left button; ********************************************* ****************************. Elseif Eax == WM_LButtondownInvoke UpdateWindow, HWnd; Instant refresh INVOKE ReleaseCaptureInvoke SendMessage, Hwnd, WM_NCLButtondown, HTCAption , 0; ******************************************************** *********************. Elseif Eax == WM_Command.if lparam == 0mov Eax, wparam.if AX == IDM_EXITCALL _QUIT.ELSEIF AX == IDM_ABOUTINVOKE DIALOGBOXPARAM , Hinstance, DLG_ABOUT, HWND, OFFSET ABOUTDIALOGPROC, DLG_ABOUT.ENDIF.Endif; ******************************************* *********************************. Elseif Eax == WM_CloseCall_quit; ******** *********************************************************** *********. ElseInvoke DefWindowProc, HWnd, UMSG, WPARAM, LPARAMRET.ENDIF; ********************************** ********************************; Note: WndProc processes Windows messages , Must return 0 in EAX; but by defWindowp The return value after the ROC processes cannot change, otherwise the window will not be displayed!; ******************************************** *********************************** * ****************************************** *********************************************************** ********* _ Init proclocal @hDCinvoke SendMessage, hWinMain, WM_SETTEXT, 0, offset szClassNameinvoke SendMessage, hWinMain, WM_SETICON, ICON_SMALL, hIconinvoke LoadBitmap, hInstance, IDB_0; charged background image mov hBmpBack, eaxinvoke _SetWindowShape, hWinMain, hBmpBack; settings window shape as the background picture invoke GetDC, hWinMainmov @ hDC, eaxinvoke CreateCompatibleDC, @ hDC; establish background and digital DCmov hDcBack, eaxinvoke ReleaseDC, hWinMain, @ hDCinvoke SelectObject, hDcBack, hBmpBackinvoke _CenterWindow, hWinMainret_Init endp;