Win32 assembly tutorial

xiaoxiao2021-03-06  38

Win32 assembly tutorial

8. Operation of the graphical interface

About GDI and bitmaps

The GDI is the most important part of Windows, which is handled by the API in the GDI32.DLL library. One of the main purposes of GDI is to support graphical programming with devices, for graphics programming under DOS. Many people may "have a sense of heart", because there are too many types of display cards in the PC, and almost every display card is different, even if there is a VESA programming, we still can't open the specific hardware, Windows GDI Make our programming of graphics, there are a lot, because GDI is the largest part of Windows, not a few words can be clear, this section is to talk about the basic processing steps and simple bitmaps under Windows. Processing does not involve the programming of DirectX. I only hope to be inspired by friends. Windows does not allow programmers to access the display hardware, all of which handles the screen is processed through the environment device (DC), each window on the screen corresponds to a DC, you can imagine the video buffer of this window District, your results of the DC will be reflected on the screen. You can also build DCs yourself in the window of the window. This is equivalent to establishing a buffer in a memory, and you save the operation of this DC in memory . You can also copy data between different DCs in different DCs. For example, you can create data in the memory DC, then copy to the DC of the window, is equivalent to completing the screen. The acquisition of DC, establishing a cancellation related API has the following:

GETDC (HWND) - A window of DC, API returns the corresponding DC handle ReleaseDC (HWnd, HDC) - Release DC Handle CreateCompaTabilityDC (HDC) acquired with GETDC - Create a memory DC from a known DC handle, Various parameters, attribute reference known DC Deletedc (HDC) - Delete DC created with CreateCompatibleDC

The above 4 APIs must be paired, and the DC acquired with Getdc must be released with ReleaseDC, and the DC established with CreateCompatibleDC must be deleted with deletedc and cannot be confused. Scope of DC: Window DC obtained with GETDC must be released as soon as possible, you should not save the DC handle between Windows, and the DC created with CreateCompaTibleDC can save long-term, for example, if you are in WM_Paint and WM_SIZE messages To operate the window's DC, you can't get Getdc in WM_INIT, then save your handle, and finally in the WM_Close message, it must be started at the place where WM_Paint and WM_SIZE will start, and it is ReleaseDC at the end of the message. Conversely CreateCompatibleDC, the opposite, you can build when WM_INIT, delete when WM_Close. If you want to draw a bit drawing into the DC, you only need to use Invoke SelectObject, HDC, hbitmap, is it simple? However, the graphic operation is not placing the bitmap in the screen, and it is also involved in the operation, such as the edge of the foreground bitmap removes the background bitmap. Windows GDI provides copy APIs between the following DCs, including copy mode: Bitblt HDCDest, XDest, YDEST, Width, Height, HDCSource, XSRC, YSRC, DWROP This API puts the XSRC, YSRC coordinate of HDCSource Copy to HDCDest's XDest, YDEST, copy size is Width, Height. PATBLT HDC, X, Y, Width, Height, DWROP are Object, HDCDest, XDest, YDEST, Width, Height, HDCSource, XSRC, YSRC, Widthsrc, Heightsrc, DWROP, such as predefined brushes, etc. Size, you can notice that it is more than two parameters compared to Bitblt, Widthsrc and HeightSRC, other are the same.

The DWROP parameters in the above API are the most critical. Its values ​​are SRCCopy, SrcPaint, Srcand, Dstinvert, etc., indicating that the source DC copy to the calculation method of the pixel after the target DC, SRCCopy indicates that the source DC coverage target DC, SrcPaint is executed OR operation, Srcand is executing the AND operation, Dstinvert is inversely, for example, if a certain point in the source DC is black, the point of the target DC corresponds to red, then use Srccopy, the point of the target DC becomes black, with SrcPaint It is still red because black (000000) OR red (0000FF) = red (0000FF). The steps corresponding to the screen or window of the screen or window are as follows.

The DC to obtain the target window with GETDC Use createCompatibleDC to create a DC in memory as a buffer to fill the memory DC or other ways to operate, one sentence, first put the things you want to display, use Bitblt to put memory DC Copy to the window DC and complete the screen refresh.

The example of this section is a screen magnifying glass that enlarges the screen content of the mouse to the screen to zoom in to your own window. Source program - assembly source file

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

PROGRAMMED by Luo Yunbin, Bigluo@telekbird.com.cn

; Website: http://asm.yeah.net

Luoyunbin's Win32 ASM Page (Luo Yunbin's Programming Park)

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

; Version Information

; Compilation Teacher supplied source program - screen amplifier

; V1.0 ------ July 1, 2000

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.386

.Model flat, stdcall

Option Casemap: None; Case Sensitive

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Include data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

INCLUDE Windows.inc

INCLUDE User32.inc

INCLUDE KERNEL32.INC

INCLUDE COMCTL32.INC

INCLUDE COMDLG32.INC

INCLUDE GDI32.INC

INCLUDELIB USER32.LIB

IncludeLib kernel32.lib

INCLUDELIB COMCTL32.LIB

INCLUDELIB COMDLG32.LIB

IncludeLib GDI32.LIB

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

; EQU data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

DLG_MAIN EQU 1000

ID_bitmap EQU 1001

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Data segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA?

HwinPic DD?

HDCMEM DD?

HBitmap DD?

HWINDESKTOP DD?

Hinstance DD?

SZBuffer DB 256 DUP (?)

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Subprogramment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

_PrOCDLGMain Proto: DWORD,: DWORD,: DWORD,: DWORD

.DATA

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Code segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.code

INCLUDE WIN.ASM

*********************************************************** *******************

_PrOcdlgmain Proc Uses EBX EDI ESI, /

HWND: DWORD, WMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

Local @stpoint: Point

Local @ hdcdesktop, @ hdcpic

MOV EAX, WMSG

.IF EAX == WM_Close

Invoke EndDialog, Hwnd, Null

Invoke Killtimer, Hwnd, 1

Invoke deletedc, HDCMEM

Invoke deleteObject, hbitmap

*********************************************************** ******************

.ELSEIF EAX == WM_INITDIALOG

Invoke getdlgitem, hwnd, id_bitmap

MOV HWINPIC, EAX

Invoke getDesktopWindow

Mov Hwindesktop, EaxInvoke SetWindowPos, HWND, HWND_TOPMOST, 0, 0, 0, 0, /

SWP_NOMOVE or SWP_NOSIZE

*********************************************************** ******************

Invoke getdc, hwindesktop

Mov @ hdcdesktop, EAX

Invoke createcompatiPLEDC, @ hdcdesktop

Mov HDCMEM, EAX

Invoke CreateCompatibleBitmap, @ hdcdesktop, 80, 80

Mov Hbitmap, EAX

Invoke SelectObject, HDCMEM, HBitmap

Invoke ReleaseDC, HWINDESKTOP, @ hdcdesktop

Invoke SetTimer, HWND, 1,100, NULL

*********************************************************** ******************

.ELSEIF EAX == WM_TIMER

Invoke getcursorpos, addr @stpoint

SUB @ stpoint.x, 20

Sub @ stpoint.y, 20

.IF @ stpoint.x <0

Mov @ stpoint.x, 0

.endif

.IF @ stpoint.y <0

Mov @ stpoint.y, 0

.endif

Invoke getdc, hwindesktop

Mov @ hdcdesktop, EAX

Invoke getdc, hwinpic

Mov @ HDCPIC, EAX

Invoke Patblt, HDCMEM, 0, 0, 80, 80, Blackness

Invoke Stretchblt, HDCMEM, 0, 0, 80, 80, /

@ hdcdesktop, @ stpoint.x, @ stpoint.y, 40, 40, srcopy

Invoke Bitblt, @ hdcpic, 0,0,80,80, /

HDCMEM, 0, 0, SRCCOPY

Invoke ReleaseDC, HWINDESKTOP, @ hdcdesktop

Invoke ReleaseDC, HwinPic, @ hdcpic

.lse

*********************************************************** *******************

Note: After the message processing of the dialog box, return True, a message that is not processed

To return false

*********************************************************** *******************

Mov Eax, False

RET

.endif

Mov Eax, True

RET

_PrOCDLGMain ENDP

*********************************************************** *******************

Start:

Invoke getModuleHandle, NULL

Mov Hinstance, EAX

Invoke Dialogboxparam, Hinstance, DLG_MAIN, NULL, OFFSET _PROCDLGMAIN, 0

Invoke EXITPROCESS, NULL

End Start

Program analysis and points

In the initialization of the program, we use the CreateComparableDC to create a memory DC to make a buffer with CreateCompatibleDC, create a bitmap and use SelectObject to set the hdcmem to this bitmap is to be HDCMEM. 80x80. Invoke getdc, hwindesktop

Mov @ hdcdesktop, EAX

Invoke createcompatiPLEDC, @ hdcdesktop

Mov HDCMEM, EAX

Invoke CreateCompatibleBitmap, @ hdcdesktop, 80, 80

Mov Hbitmap, EAX

Invoke SelectObject, HDCMEM, HBitmap

Invoke ReleaseDC, HWINDESKTOP, @ hdcdesktop

Then in the WM_TIMER timer message of the program, let's get the handle of the text box in the desktop and dialog box, then remove the memory DC to black with PATBLT, and copy 40x40 from the desktop DC with Stretchblt. In the area to memory DC, the new size is 80x80 (the enlargement function is achieved), the copy of the copy is obtained with getCursorpos, which is the current location of the mouse, and finally copy the memory DC to the dialog in the dialog. If you copy the desktop DC to the dialog box, it is possible when the mouse moves onto the edge edge, because the point outside the screen is invalid, so some of the dialog box will be placed, you can change the program.

Invoke getcursorpos, addr @stpoint

Invoke getdc, hwindesktop

Mov @ hdcdesktop, EAX

Invoke getdc, hwinpic

Mov @ HDCPIC, EAX

Invoke Patblt, HDCMEM, 0, 0, 80, 80, Blackness

Invoke Stretchblt, HDCMEM, 0, 0, 80, 80, /

@ hdcdesktop, @ stpoint.x, @ stpoint.y, 40, 40, srcopy

Invoke Bitblt, @ hdcpic, 0,0,80,80, /

HDCMEM, 0, 0, SRCCOPY

Invoke ReleaseDC, HWINDESKTOP, @ hdcdesktop

Invoke ReleaseDC, HWINPIC, @ hdcpic9. General article (1) Window of Complex Shape Overview In the eighth Win32ASM tutorial, the message box, dialog, menu, resources, gdi and other content have been initially designed. Most of the Windows interface, in the continued new Windows other parts, such as multithreading, file operation, memory, I first integrate the previous content and add some 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 create 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; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>

Whether to include debug code

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Debug = 0

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

PROGRAMMED by Luo Yunbin, Bigluo@telekbird.com.cn

; Website: http://asm.yeah.net

Luoyunbin's Win32 ASM Page (Luo Yunbin's Programming Park)

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>

; Special Shape Window Demo Ver 1.0

The shape of the window can be automatically set according to the bitmap.

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.386

.Model flat, stdcall

Option Casemap: None; Case Sensitive

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Include data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

INCLUDE Windows.inc

INCLUDE User32.inc

INCLUDE KERNEL32.INC

INCLUDE COMCTL32.INC

INCLUDE COMDLG32.INC

Include shell32.inc

INCLUDE GDI32.INC

INCLUDELIB USER32.LIB

IncludeLib kernel32.lib

INCLUDELIB COMCTL32.LIB

INCLUDELIB COMDLG32.LIB

IncludeLib shell32.lib

IncludeLib GDI32.LIB

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

************** EQU data ******************************************** *

IDI_MAIN EQU 1; icon

IDC_HANDLE EQU 2; CURSOR

************** EQU data ******************************************** *

DLG_ABOUT EQU 1200; Dialog - About

ID_ABOUT_OK EQU 1201

ID_EMAIL EQU 1202

ID_HOMEPAGE EQU 1203

************** EQU data ******************************************** *

IDM_MAIN EQU 2000

IDM_ABOUT EQU 2001

IDM_EXIT EQU 2002

************** EQU data ******************************************** *

IDB_0 EQU 3000; Bitmap

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Data segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA?

Hinstance DD?

HwinMain DD?

Hicon DD?

HCURSOR DD?

HMENU DD?

HBMPBACK DD?; Background Bitmap

HDCBACK DD?

************** Data segment *************************************************** ***. Data

SzclassName DB 'ShapeWindow', 0

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Code segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.code

IF Debug

INCLUDE Debug.asm

ENDIF

*********************************************************** *******************

Set the shape of the window as a BMP graphic shape

; Parameter: Window handle, BMP graphics handle

[Enter BMP graphics requirements: 0,0 color is background color

*********************************************************** *******************

_SETWINDOWSHAPE PROC HWND: DWORD, HBITMAP: DWORD

Local @HDC: DWORD, @ HBMPDC: DWORD

Local @stps: Paintstruct

Local @STRECT: RECT

Local @stbmp: Bitmap

Local @dwx: dWord, @ dwy: dword, @ dwstartx: dword

Local @hrgn: dWord, @ hrgntemp: dword

Local @RGBBACK: DWORD

Invoke GetObject, Hbitmap, Sizeof Bitmap, Addr @stbmp

Invoke getWindowRect, hwnd, addr @stRect

Invoke ShowWindow, HWnd, SW_HIDE

Invoke movewindow, hwnd, @ strect.Left, @ strect.top, /

@ stbmp.bmwidth, @ stbmp.bmheight, false

Invoke getdc, hwnd

Mov @ HDC, EAX

Invoke CreateCompatibledc, @ hdc

Mov @ HBMPDC, EAX

Invoke SelectObject, @ hbmpdc, hbitmap

************** Calculated window shape ***************************************** *********

Invoke getpixel, @ HBMPDC, 0, 0

Mov @ rgbback, EAX

Invoke CreateRectrgn, 0, 0, 0, 0

Mov @ hrgn, EAX

Mov @ dwy, 0

.While true

MOV @ dwx, 0

Mov @ dwstartx, -1

.While true

Invoke getpixel, @ HBMPDC, @ dwx, @ dwy

.IF @dwstartx == -1

.IF EAX! = @RGBBACK

MOV EAX, @ dwx

Mov @ dwstartx, EAX

.endif

.lse

.IF EAX == @RGBBACK

Mov ECX, @ dwy

Inc ECX

Invoke createRectRgn, @ dwstartx, @ dwy, @ dwx, ecx

Invoke Combinergn, @ hrgn, @ hrgn, eax, rgn_or

Mov @ dwstartx, -1

.lse

MOV EAX, @ dwx

.IF EAX == @ stbmp.bmwidth

INC EAX

Mov ECX, @ dwy

Inc ECX

Invoke CreateRectrgn, @ dwstartx, @ dwy, eax, ECX

Invoke Combinergn, @ hrgn, @ hrgn, eax, rgn_or

Mov @ dwstartx, -1

.endif

.endif

.endif

INC @dwx

MOV EAX, @ dwx

.break .if eax> @ stbmp.bmwidth

.endw

Inc @dwy

Mov Eax, @ dwy

.break .if eax> @ stbmp.bmheight

.endw

Invoke setwindowrgn, hwnd, @ hrgn, true

*********************************************************** *******************

Invoke Bitblt, @ hdc, 0,0, @ stbmp.bmwidth, @ stbmp.bmheight, /

@ HBMPDC, 0, 0, Srccopy

Invoke deletedc, @ HBMPDC

Invoke ReleaseDC, HWnd, @ HDC

Invoke InvalidateERECT, HWND, NULL, -1

RET

_SETWINDOWSHAPE ENDP

*********************************************************** *******************

; Move the window to the middle of the screen

; Parameter: Window Handle

*********************************************************** *******************

_CenterWindow Proc HWND: DWORD

Local @StRectdesktop: Rect, @ strectwin: Rect

Local @dwwidth: dWord, @ dwheight: dword

Invoke getWindowRect, hwnd, addr @stRectwin

Invoke getDesktopWindow

MOV EBX, EAX

Invoke GetWindowRect, EBX, Addr @STRECTDESKTOP

Mov Eax, @ strecTwin.bottom

Sub eax, @ strecTwin.top

Mov @ dwheight, EAX

Mov Eax, @ strecTwin.right

Sub eax, @ strecTwin.Leftmov @ dwwidth, EAX

Mov EBX, @ strectdesktop.bottom

Sub ebx, @ dwheight

SHR EBX, 1

MOV ECX, @ strectdesktop.right

Sub ECX, @ dwwidth

SHR ECX, 1

Invoke MoveWindow, HWnd, ECX, EBX, @ dwwidth, @ dwheight, false

RET

_CenterWindow Endp

*********************************************************** *******************

INCLUDE ABOUT.ASM

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Procedure

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Start:

Call_winmain

Invoke EXITPROCESS, NULL

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Main window program

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

_WinMain Proc

Local @stwcmain: WNDCLASSEX

Local @stmsg: msg

Invoke INITCOMMONCONTROLS

Invoke getModuleHandle, NULL

Mov Hinstance, EAX

Invoke Loadicon, Hinstance, IDI_MAIN

MOV Hicon, EAX

Invoke Loadmenu, Hinstance, IDM_MAINIVOKE GETSUBMENU, EAX, 0; Popup menu to use submenu

Mov Hmenu, EAX

************** Register window **************************************** **********

Invoke loadCursor, 0, IDC_ARROW

Mov @ stwcmain.hcursor, EAX

Mov @ stwcmain.cbsize, sizeof wndclassex

Mov @ stwcmain.hiconsm, 0

Mov @ stwcmain.style, cs_hredraw or cs_vredraw

Mov @ stwcmain.lpfnwndproc, Offset WNDMAINPROC

Mov @ stwcmain.cbclsextra, 0

Mov @ stwcmain.cbwndextra, 0

Mov Eax, Hinstance

Mov @ stwcmain.hinstance, EAX

Mov @ stwcmain.hicon, 0

Mov @ stwcmain.hbrbackground, color_window 1

Mov @ stwcmain.lpszclassname, offset szclassname

Mov @ stwcmain.lpszMenuname, 0

Invoke registerclassex, addr @stwcmain

**************** Establish an output window ************************************** ************

; Property: No title bar, not displayed in the task bar

*********************************************************** *******************

Invoke CreateWindowex, WS_EX_TOOLWINDOW, /

Offset SzclassName, NULL, /

WS_POPUP or WS_SYSMENU, /

0, 0, 1, 1, /

NULL, NULL, HINSTANCE, NULL

Invoke ShowWindow, Hwinmain, SW_SHOWNORMAL

Invoke UpdateWindow, HwinMain

************** Message loop ***************************************** ***********

.While true

Invoke GetMsg, NULL, 0, 0

.break .if eax == 0

Invoke TranslateMsg, Addr @stmsg

Invoke DispatchMessage, Addr @STMSG

.endw

RET

_WinMain ENDP

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

WNDMAINPROC PROC Uses EBX EDI ESI, /

HWnd: DWORD, UMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

Local @stpos: Point

Local @stps: Paintstruct, @ HDC: DWORDMOV EAX, UMSG

.IF EAX == WM_CREATE

Mov Eax, HWnd

Mov Hwinmain, EAX

Call_init

*********************************************************** *******************

.ELSEIF EAX == WM_PAINT

Invoke Beginpaint, Hwnd, Addr @stps

Mov @ HDC, EAX

Mov Eax, @ stps.rcpaint.right.right

Sub eax, @ stps.rcpaint.Left

Mov ECX, @ stps.rcpaint.bottom

Sub ECX, @ stps.rcpaint.top

Invoke Bitblt, @ hdc, @ stps.rcpaint.Left, @ stps.rcpaint.top, eax, ECX, /

HDCBACK, @ stps.rcpaint.Left, @ stps.rcpaint.top, srccopy

Invoke endpaint, hwnd, addr @stps

*********************************************************** *******************

Due to no menus, the following code is used to pop up the popup menu when the right button is pressed.

*********************************************************** *******************

.ELSEIF EAX == WM_RBUTTONDOWN

.IF WPARAM == MK_RBUTTON

Invoke getcursorpos, addr @stpos

Invoke TRACKPOPUPMENU, HMENU, TPM_LEFTALIGN, @ stpos.x, @ stpos.y, null, hwnd, null

.endif

*********************************************************** *******************

Due to the no title bar, the following code is used to move the window when the left button is pressed.

*********************************************************** *******************

.ELSEIF EAX == WM_LBUTTONDOWN

Invoke UpdateWindow, HWnd; Instant Refresh

Invoke ReleaseCapture

Invoke SendMessage, Hwnd, WM_NCLButtondown, HTCAPTION, 0

*********************************************************** *******************

.ELSEIF EAX == WM_COMMAND

.IF lparam == 0

Mov Eax, WPARAM

.IF AX == idm_exit

Call_quit

.ELSEIF AX == IDM_ABOUT

Invoke Dialogboxparam, Hinstance, DLG_About, Hwnd, Offset AboutDialogproc, DLG_ABOUT

.endif

.endif

*********************************************************** *******************

.ELSEIF EAX == WM_Close

Call_quit

*********************************************************** *******************. ELSE

Invoke DefWindowProc, Hwnd, UMSG, WPARAM, LPARAM

RET

.endif

*********************************************************** *******************

Note: After WndProc processes the Windows message, you must return 0 in Eax.

But the return value after the DEFWINDOWPROC cannot be changed, otherwise the window

; Will not be displayed!

*********************************************************** *******************

XOR EAX, EAX

RET

WNDMAINPROC ENDP

*********************************************************** *******************

_Init proc

Local @HDC

Invoke SendMessage, Hwinmain, WM_SETTEXT, 0, OFFSET SZCLASSNAME

Invoke SendMessage, HwinMain, WM_SETITION, ICON_SMALL, HICON

Invoke loadbitmap, hinstance, idb_0; loading background picture

MOV HBMPBACK, EAX

Invoke _SetWindowshape, hwinmain, hbmpback; set window shape is background picture

Invoke getdc, hwinmain

Mov @ HDC, EAX

INVOKE CREATECMOMPALEDC, @ HDC; create background and digital DC

Mov HDCBACK, EAX

Invoke ReleaseDC, Hwinmain, @ HDC

Invoke SelectObject, HDCBACK, HBMPBACK

Invoke _CenterWindow, HwinMain

RET

_Init ENDP

*********************************************************** *******************

_Quit Proc

Local @stwindow: Rect

Invoke Destroymenu, Hmenu

Invoke deletaedc, HDCBACK

Invoke deleteObject, HBMPBACK

Invoke DestroyWindow, HwinMain

Invoke PostquitMessage, NULL

RET

_Quit ENDP

*********************************************************** *******************

End Start

When the program analyzes and points create a window, the window style is WS_POPUP, so the created window does not have a title bar, so the window is suitable for window invoke createWindowEx, WS_EX_TOOLWINDOW, /

Offset SzclassName, NULL, /

WS_POPUP or WS_SYSMENU, /

0, 0, 1, 1, /

NULL, NULL, HINSTANCE, NULL, but when the window does not have a title bar, we cannot move the window with the way to drag the title bar. If the window does not care in the middle of the screen, it is obviously not possible, there is an alternative method, we You can respond to messages on the left mouse button, you want the window to send WM_NCLBUTTONDOWN (Non-Customer Mouse Pressing Message) in the WM_LButtondown message to simulate the mouse in the Title bar to implement the function. .ELSEIF EAX == WM_LButtondownInvoke UpdateWindow, HWnd; Instant Refresh

Invoke ReleaseCapture

Invoke SendMessage, Hwnd, WM_NCLButtondown, HTCAPTION, 0

10. Application Overview of Timers The timer for Windows is an input device that periodically notifies the application at the specified interval time. It can be used to send a WM_TIMER message to the specified window or call the specified process to execute the user's program. The timer's application mainly includes some places:

Clock Program - Obviously, this is the most direct application of the timer. Multi-task - If the program has a large amount of data processing, in addition to multi-threaded approach, you can use the timer to process a small piece of content in each timer message. The condition of the timing display program - Timer is equivalent to the program that hooks in the INT 1Ch in the DOS programming, which can schedule the program to run, such as the amount of content sent, receive more content, etc. Wait. The use of timers in the game program can eliminate errors caused by the delay in different processors to hold speeds. For data stream processing - in the playback of audio, video, you need to process a segment of data over a period of time. In general, the only way to implement accuracy in DOS is to handle the program in the int 1ch clock interrupt, but you must comply with a lot of specifications, and in Windows Timers, you can use the setTimer function to assign more than one Timer, for example, in your text editing program, you can use a 1 second timer to display the clock in the status bar while assigning a 10-minute timer to implement the function of the timing. The timer is actually a extension of Windows to the clock interrupt. Its essence is still based on the clock interrupt, so you can't set the interval of the timer to 55 milliseconds, in addition, the accuracy of the timer is also 55 milliseconds Multiple, for example, you set a 1 second timer, which actually happened at every 989 milliseconds. Using clocks under DOS, Windows's timer has some points below:

In DOS, your program may be interrupted by int 1ch, and in Windows, Windows puts the timer message through the WM_TIMER message into the normal message queue, so you don't have to worry about your program in other processing. Interrupt. It is impossible to have two WM_Timer messages simultaneously, if a window is still in a message queue, the two messages will be merged into one, so the WM_TIMER message may be lost when the program is relatively busy. The level of the WM_TIMER message is very low, and the program only receives the WM_TIMER message if there is no other message in the message queue, you can verify the following horse method: Press and hold the title bar mobile window on a window set the timer. You will find that the timer stops working. When you release the mouse, the WM_TIMER message lost in this process is not added, so if you design a clock program, you can't use the timer message to count, but must Get the correct system time each time in the message. Telling so many timers, the following is the timer-related API, you will find that the Timer's API is really less and simple in addition to these features you should pay attention to in use:

Establishment timer SetTimer (HWND hWnd, // handle of window for timer messages UINT nIDEvent, // timer identifier UINT uElapse, // time-out value TIMERPROC lpTimerFunc // address of timer procedure); hWnd WM_TIMER transmission windows is the window, and NidEvent is the number of timers, which appears in the WPARAM parameter in the WM_Timer, which is used to distinguish which timer is generated by a plurality of timers. UELAPSE is a timer interval for milliseconds. If you want to set a 1 second timer, this value is 1000, and lptimerfunc is the process of processing timer messages. If this parameter is not null, Windows will call lptimerfunc specified after the time. Procedure, the parameter called is called Callback TimerProc (HWND, WM_TIMER, ITIMERID, DWTIME), and itimerid is the timer ID, DWTIME is a system time; if the lptimerfunc parameter is null, Windows puts the WM_TIMER message into the message loop, the message hWnd is The HWnd specified in the first parameter, that is, the WM_TIMER message is sent to this window. Also, if your program is not window, you can also use this method to establish Timers: Invoke SetTimer, Null, Null, UELAPSE, TIMERPROC, and functions return a system-defined Timerid for you to use in KillTimer. Cance the timer KillTimer (HWND HWND, // Handle Of WINDOW THAT INSTALLED TIMER UIDEVENT / / TIMER Identifier); Canceling Timer Simply call the killtimer function when you have the hWnd and UidEvent when SetTimer. In the example program in this section, I use setTimer to build two timers in the WM_INIT message in the dialog, and the time is 500ms and 200ms, and then replace the picture on the button in a fixed timer message at a distance of 0.5 seconds, at the interval To replace the small icon on the title bar in a timer message, you can see the animation. Source program - assembly source file; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Yunbin, bigluo@telekbird.com.cn

; Website: http://asm.yeah.net

Luoyunbin's Win32 ASM Page (Luo Yunbin's Programming Park)

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>

; Compilation Teaching Edition Example - Timer

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.386

.Model flat, stdcall

Option Casemap: None; Case Sensitive

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Include data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

INCLUDE Windows.inc

INCLUDE User32.inc

INCLUDE KERNEL32.INC

INCLUDE COMCTL32.INC

INCLUDE COMDLG32.INC

INCLUDELIB USER32.LIB

IncludeLib kernel32.lib

INCLUDELIB COMCTL32.LIB

INCLUDELIB COMDLG32.LIB

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

; EQU data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Idi_main EQU 1

IDI_MOON1 EQU 2

IDI_MOON2 EQU 3

IDI_Moon3 EQU 4

IDI_MOON4 EQU 5

IDI_MOON5 EQU 6

IDI_MOON6 EQU 7

IDI_MOON7 EQU 8

IDI_MOON8 EQU 9

DLG_MAIN EQU 1000

ID_Moon EQU 1001

ID_TIMER1 EQU 1

ID_TIMER2 EQU 2

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Data segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA?

Hinstance DD?

DWCOUNTER1 DD?

DWCOUNTER2 DD?

Hicon1 DD?

Hicon2 DD?

Hicon3 DD?

Hicon4 DD?

Hicon5 DD?

Hicon6 DD?

Hicon7 DD?

Hicon8 DD?

SZBuffer DB 256 DUP (?)

.DATA

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Code segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder

*********************************************************** *******************

_PrOcdlgmain Proc Uses EBX EDI ESI, /

HWND: DWORD, WMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

MOV EAX, WMSG

*********************************************************** *******************

.IF EAX == WM_Close

Invoke killtimer, hwnd, id_timer1

Invoke KillTimer, HWnd, ID_TIMER2

Invoke EndDialog, Hwnd, Null

*********************************************************** *******************

.ELSEIF EAX == WM_INITDIALOG

Mov Edi, Offset HiCon1

MOV EBX, IDI_MOON1

MOV ECX, 8

@@:

Push ECX

INVOKE LOADICON, HINSTANCE, EBX

CLD

Stosd

Inc EBX

POP ECX

Loop @B

Invoke setTimer, HWND, ID_TIMER1, 500, NULL

Invoke settimer, hwnd, id_timer2,200, null

Invoke SendMessage, Hwnd, WM_SETICON, ICON_SMALL, HICON1

*********************************************************** *******************

.ELSEIF EAX == WM_TIMER

.IF wparam == id_timer1

INC DWCOUNTER1

.IF dwcounter1 == 8

Mov dwcounter1,0

.endif

Mov Eax, DWCOUNTER1

SHL EAX, 2

Add Eax, Offset Hicon1

Mov Eax, [EAX]

Invoke SendMessage, Hwnd, WM_SETICON, ICON_SMALL, EAX

.lse

Inc dwcounter2

.IF dwcounter2 == 8

Mov dwcounter2,0

.endif

Mov Eax, dwcounter2

SHL EAX, 2

Add Eax, Offset Hicon1

Mov Eax, [EAX]

Invoke Senddlgitemmessage, Hwnd, ID_Moon, BM_SetImage, Image_ICON, EAX

.endif

*********************************************************** *******************

.lse

Mov Eax, False

RET

.endif

Mov Eax, True

RET

_PrOCDLGMain ENDP

*********************************************************** ****************** START:

Invoke getModuleHandle, NULL

Mov Hinstance, EAX

Invoke Dialogboxparam, Hinstance, DLG_MAIN, NULL, OFFSET _PROCDLGMAIN, 0

Invoke EXITPROCESS, NULL

*********************************************************** *******************

The analytical points of the End Start program have the above introduction, this program is easy to understand, in the WM_TIMER message, the TimerId in WPARER can distinguish the message generated by which timer generated. In the WM_CLOSE message, the timer is canceled by KillTimer. The icons in this program are defined in the resource file. When the dialog is established, first use LoadICON to load, then save a picture number DWCOUNTER1 and DWCUNTER2 for two timers, and use WM_SETICON and BM_SETIMAGE in the timer message. The message is set to set the icon of the window title and button. 11. Process Control Overview Process Control Simation Specifications It is equivalent to executing another program in a program, you can imagine it to perform another program with int 21h / 4bh function in DOS, if you do another program For a purposes, there are many ways in Windows, such as using shellexecute, but these APIs are just "execution", the meaning of process control is to create a process and can end the process through the process handle, and you can also pass The process handle is tracked, and you can read the memory space of the writing sub-process with ReadProcessMemory and WriteProcessMemory. Process Control The relevant API to use has the following: Create a function of the process for CREATEPROCESS, which is more complicated, with ten parameters, but there is a good message to use NULL. BOOL CreateProcess (LPCTSTR lpApplicationName, // execute the program file name LPTSTR lpCommandLine, // parameter line LPSECURITY_ATTRIBUTES lpProcessAttributes, // process safety parameters LPSECURITY_ATTRIBUTES lpThreadAttributes, // thread safety parameters BOOL bInheritHandles, // inheritance flag DWORD dwCreationFlags, // create tags LPVOID LPENVIRONMENT, / / ​​Environment Variable LPCTSTSTAR LPCURRENTDIRECTORY, / / ​​Run the initial directory of the child Process LPStartupinfo LPStartupinfo, // Create the relevant parameter of the child process LPPROCESS_INFORMATION LPPROCESSINFORMATION // created the information used to create sub-process); various parameters as follows:

LPApplicationName: To execute the program's file name, you can also include the execution file name in the next parameter lpCommandline, and then set this parameter to NULL. LPCommandline: For parameter line, if the parameters can be null, you can set the following when passing to the process: lpapplicationName = file name; lpchaMMandLine = parameter, or lpApplicationName = Null; lpCommandline = file name parameter. LPPRocessAttributes, LPTHREADATIADATTRIBUTES: The created process and thread security properties are described, and if null is used to represent the default security description. BinheritHandles: Indicates whether the handle in the current process can be inherited by the sub-process that can be created. DWCREATIONFLAGS: Represents the creation tag, which can set the creation status and priority of the process via this tag. Commonly used tags: create_new_console: Create a new console for the child process. CREATE_SUSPENDED: The child process is hang when creating. If this parameter is specified, the process of executing the createProcess is just loaded, but not immediately started, but must wait until the main program is called RESUMETHREAD to continue. High_priority_class / normal_priority_class: High / normal priority. LpenVironment: Indicates the environment variable used by the child process. If null, the same environment variable is used to use the current process. LpCurrentDirectory: Indicates the initial directory of the sub-process run. LPStartupInfo: STARTUPINFO structure, used to set various properties when creating sub-processes. The LPPROCESSINFORMATION: Process_information structure is used to receive relevant information after the process is created, which is filled out by the system.

Calling the CreateProcess function There is three parameters, which is required, one in lpapplicationName or lpCommandline specifies the file name, the second is the LPstartupInfo structure, the third is the Process_information structure, because the process_information structure returns the handle after the process is established, and everything will be used to use these returns. Handle, it is fillised by the system, the structure is described as follows: typedef struct _process_information {handle hthread; // process handle Handle Hthread; // Process main thread handle DWord dWProcessID; // Process IDDWORD DWTHREADID; // Main thread ID } Process_information; there is another key structure Startupinfo, which is defined as follows: typedef struct startupinfo {dWord CB; // Structural length lptstr lpreserved; // Reserved lptstr lptisektop; // Reserved LPTSTR LPTITLE; // If the console process Then, the title DWORD DWX; // window location dword dwy; // window location DWORD dwysize; // window size DWORD dwysize; // window size DWORD dwxcountchars; // console window word symbol width DWORD DWYCOUNTCHARS; // Control Table window word symbol Height DWORD DWFILLATTRIBUTE; // Console Window Fill mode DWORD DWFLAGS; // Create tag Word wshowWindow; // window display tag, like showWindow's mark word cbreserved2; // lpbyte lpreserved2; // handle hstdinput; // Handle HstdInput; / Stand-input handle Handle HSTDOUTPUT; // Standard Output Handle Handle HSTDERROR; // Standard Error Handle} Startupinfo, * LPStartupInfo; DWFlags DwFLAGS Specifies whether other fields are valid, such as: dwflags contains Startf_USESize to indicate dwxsize and dwysize valid, including Startf_useposition means DWX and DW Y is effective, and so on. If there is not a special requirement, we don't have to fill in this structure yourself, just use getStartupInfo to make Windows to fill in you, this way, the statement to create a process is: ... StStartup StartupinfostProcinfo Process_information

StProcInfo PROCESS_INFORMATION ... invoke GetStartupInfo, addr stStartUpinvoke CreateProcess, NULL, addr szFileName, NULL, NULL, NULL, NORMAL_PRIORITY_CLASS, NULL, NULL, offset stStartUp, offset stProcInfo ... If successful, eax will return Non-zero value, pay attention to returning HProcess in the Process_information structure, which is used in many operations. Forced an API of a process to TerminateProcessBool TerminateProcess (Handle HProcess // Procedure Code); you can use statements invoke terminateProcess, StructProcinfo.hprocess, 0 to end the process, pay attention to if possible, try to Don't force other processes in the program, because the process ended using TERMINATEPROCESS, it is loaded with the DLL cannot be uninstalled correctly. This may cause an invalid occupancy of system resources. The best way to use EXITPROCESS to exit in the process. Query a process status API is getExitcodeProcess. Bool getExitcodeProcess (Handle HProcess, // Handle To The Process To Receive Termination Status); if the process has not yet quilt, the function will return Still_Active. This API is back. Waiting for the process can use WaitForsingleObject This API is not single for the process, others can also be used in threads, but we generally use it to wait for the execution of the process, its declaration is: DWORD WAITFORSINGLEOBJECT (Handle Hhandle, // handle of object to wait forDWORD dwMilliseconds // time-out interval in milliseconds); if we wait for the process to be executed for one second, you can invoke WaitForSingleObject, stProcInfo.hProcess, 1000 if you want to wait until the end of the process, you can use WaitForSingleObject, stProcInfo.hProcess, Infinite, Infinite in Parameter 2 is defined in Windows.inc, meaning infinity waiting. Finally, when the process handle is no longer used, don't forget to use CloseHandle to close the HProcess and Hthread, otherwise the resource of the system handle will be watted. Source program - assembly source file. 386

.Model flat, stdcall

Option Casemap: None; Case Sensitive

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Include data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder Windows.inc

INCLUDE User32.inc

INCLUDE KERNEL32.INC

INCLUDE COMCTL32.INC

INCLUDE COMDLG32.INC

INCLUDE GDI32.INC

INCLUDELIB USER32.LIB

IncludeLib kernel32.lib

INCLUDELIB COMCTL32.LIB

INCLUDELIB COMDLG32.LIB

IncludeLib GDI32.LIB

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

; EQU data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

DLG_MAIN EQU 3000

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

ID_BROWSE EQU 3001

ID_Run EQU 3002

ID_EXIT EQU 3003

ID_Text EQU 3004

F_Running EQU 0001H; Process is in operation

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Data segments

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA?

StSTARTUP STARTUPINFO

STPROCINFO Process_information

StopenFileName OpenFileName

HRUNTHREAD DD?

Hinstance DD?

HwinMain DD?

Hicon DD?

SZBuffer DB 512 DUP (?)

DWFLAG DD?

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA

SZEXCUTE DB 'Perform (& E)', 0; button text

SZKILL DB 'Termination (& E)', 0

SZEXCUTEERROR DB 'Launches an application error! ', 0

SZTITLEOPEN DB "Open Executable File ...", 0

SZEXT DB '* .EXE', 0

SZFilter DB 'Excutable Files', 0, '*. EXE; *. com', 0

DB 0

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Code segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder

IF Debug

INCLUDE Debug.asm

ENDIF

INCLUDE WIN.ASM

*********************************************************** *******************

Implementing threads used

1. Establish a process with CreateProcess

; 2. Waiting for the process of waiting for the process of WaitforsingleOject

*********************************************************** *******************

_Runthread Proc Uses EBX ECX EDX ESI EDI, /

DWParam: DWORD

OR dwflag, f_running

*********************************************************** *******************

; Cancel the "exit" button and change the "execution" button to "abort"

*********************************************************** *******************

Invoke getdlgitem, hwinmain, id_exit

Invoke EnableWindow, EAX, FALSE

Invoke Senddlgitemmessage, Hwinmain, ID_Run, WM_SETTEXT, 0, OFFSET SZKILL

*********************************************************** *******************

; Execute file, wait for the end to end if successful

*********************************************************** *******************

Invoke GetStartupinfo, AddR StStartup

Invoke CreateProcess, NULL, AddR Szbuffer, NULL, NULL, /

NULL, NORMAL_PRIORITY_CLASS, NULL, NULL, OFFSET StStartup, Offset StPROCINFO

.IF EAX! = 0

Invoke WaitforsingleObject, StProcinfo.hprocess, Infinite

Invoke CloseHandle, StProcinfo.hprocess

Invoke Closehandle, StProcinfo.hthread

.lse

Invoke Messagebox, Hwinmain, Addr SzexcuteError, NULL, MB_OK OR MB_ICONERROR

.endif

*********************************************************** *******************

; Enable "Exit" button and turn the "abort" button to "execution"

*********************************************************** *******************

Invoke getdlgitem, hwinmain, id_exit

Invoke EnableWindow, Eax, True

Invoke Senddlgitemmessage, Hwinmain, ID_Run, WM_SETTEXT, 0, OFFSET SZEXCUTE

And dwflag, not f_running

RET

_RunthRead Endp

*********************************************************** *******************

Window program

*********************************************************** *******************

DialogmainProc Proc Uses EBX EDI ESI, /

HWND: DWORD, WMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

MOV EAX, WMSG

*********************************************************** *******************

.IF EAX == WM_INITDIALOG

Mov Eax, HWnd

Mov Hwinmain, EAX

Call_init

*********************************************************** *******************

.ELSEIF EAX == WM_Close

Invoke EndDialog, HwinMain, Null

*********************************************************** *******************

.ELSEIF EAX == WM_COMMAND

Mov Eax, WPARAM

.IF AX == id_browse

Call _browsefile

Call_checktext

.ELSEIF AX == id_text

Invoke Getdlgitemtext, Hwinmain, ID_Text, Addr Szbuffer, 512

Call_checktext

.ELSEIF AX == id_run

*********************************************************** *******************

If the thread is established if not in the execution (dwflag is not set), execute the program in the thread

If it is already in execution, use TerminateProcess to terminate execution

*********************************************************** *******************

Test dwflag, f_running

.IF ZERO?

Invoke CreateThread, Null, Null, Offset _Runthread, /

NULL, NULL, OFFSET HRUNTHREAD

.lse

Invoke TerminateProcess, StProcinfo.hprocess, -1

.endif

.ELSEIF AX == id_exit

Invoke EndDialog, HwinMain, Null

.endif

.lse

*********************************************************** *******************

Note: After the message processing of the dialog box, return True, a message that is not processed

To return false

*********************************************************** *******************

Mov Eax, False

RET

.endif

Mov Eax, True

RET

DialogmainProc ENDP

*********************************************************** **************; program entry

*********************************************************** *******************

Start:

Invoke INITCOMMONCONTROLS

Invoke getModuleHandle, NULL

Mov Hinstance, EAX

Invoke Dialogboxparam, Hinstance, DLG_MAIN, NULL, OFFSET DIALOGMAINPROC, 0

Invoke EXITPROCESS, NULL

*********************************************************** *******************

_Init proc

Invoke _CenterWindow, HwinMain

Invoke Senddlgitemmessage, HwinMain, ID_Text, EM_LIMITTEXT, 512, NULL

Invoke getdlgitem, hwinmain, id_run

Invoke EnableWindow, EAX, FALSE

RET

_Init ENDP

*********************************************************** *******************

; According to the TEXT Control, there is a character that determines whether to "execute" button disable.

*********************************************************** *******************

_CheckText Proc

Invoke Getdlgitemtext, Hwinmain, ID_Text, Addr Szbuffer, 512

Invoke lstrlen, Addr Szbuffer

.IF EAX! = 0 || (dwflag & f_running)

Invoke getdlgitem, hwinmain, id_run

Invoke EnableWindow, Eax, True

.lse

Invoke getdlgitem, hwinmain, id_run

Invoke EnableWindow, EAX, FALSE

.endif

RET

_CheckText ENDP

*********************************************************** *******************

_Browsefile Proc

Mov stopenfilename.flags, OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST

Mov StopenFileName.lstructSize, SizeOf StopenFileName

Mov Eax, HwinMain

Mov StopenFileName.hwndowner, EAX

Mov stopenfilename.lpstrfilter, offset szfilter; extension

Mov stopenfilename.lpstrfile, offset szbuffer; file name buffer

Mov stopenfilename.nmaxfile, 512; file name buffer length

Mov stopenfilename.lpstrinitialdir, 0

Mov StopenFileName.lpstitle, Offset Sztitleopen

Mov stopenfilename.lpstrdefext, offset szext

Invoke GetopenFileName, Offset StopenFileName

.IF EAX == false

RET

.endif

Invoke setdlgitemtext, hwinmain, id_text, addr szbufferret

_Browsefile Endp

*********************************************************** *******************

End Start

Program analysis and key points This program is using calling getopenfilename or enter the execution file name in the text box, and then builds the process via the createProcess, and finally use the waitforsingleObject wait process. If you wait during the dialog process, you will return to the process. It is unable to respond before, so the program creates a thread with CreateThread to implement this process, and when the child is returned, the thread ends. 0 digits in dwflag are flag bits, indicating whether the procedure is running, if this location 1, press the "Termination" button to force the terminator process with TerminateProcess. 12. Pipeline Overview Windows introduces multi-process and multi-threaded mechanisms. At the same time, there is also a communication method between multiple processes, including clipboard, DDE, OLE, pipeline, etc. Compared to other communication means, the pipe has its own restrictions and characteristics, and the pipeline is actually a shared memory area, process Place the shared message there. And provide information exchange through some APIs. The pipe is two heads, each of each head connected to a process or different code of the same process, with two types of pipes, anonymity and naming; according to the pipeline transfer direction, single Bidirectional. Depending on the characteristics of the pipeline, the named pipe is usually used between the processes running on different computers in a network environment (of course, in different processes of the same machine) it can be unidirectional or two-way; and anonymous pipeline only Can be used in the same computer, it can only be one-way. Anonymous pipe is actually achieved by a famous pipe for a specified name. The benefit of using the pipe is that reading and writing It is used by the API for file operation, and the results are the same as the operational file. Even if you communicate with a naming pipe between different computers, you don't have to know the specific details of the network communication between networks. We briefly introduce the use of named pipes. The named pipe is established by the server-side process. The naming of the pipe must follow the specific naming method, that is, "//pipe/ pipe name", when used as a client, use "// computer name // PIPE / Pipe name "to open the use, the specific steps are as follows:

The server creates an instance of a named pipe through the function CreateNameDpipe and returns the handle for future operation, or creates a new instance for existing pipes. The server listened to the connection request from the client, which is implemented through the connection function. The client is waiting for the appearance of the pipe through function WaitNameDpipe. If the timeout value becomes zero, there is a pipe to use, then WaitNameDpipe will return True and call the server connection by calling CREATEFILE or CALLNAMEDPE. At this point, the server will accept the client's connection request, successfully established a connection, the server connectNamedPipe returns the TRUE to establish a connection, the client and the server can use the readFile and WriteFile, and use the obtained pipe file handle to exchange information. When the client is ended with the server, the client calls Closefile, and the server then calls DisconnectNamedPipe. Finally, the function closehandle is called to turn off the pipe. Since the program is used as the client, the program must know the name of the pipe, so more in the server / workstation program written in the same "author", you can't find a program to ask it to write the program. By named pipe communication. The use of anonymous pipeline is completely different. It allows you and completely unpacked process communication, the condition is that this process enters the output through the console "console", typical example is the old DOS application, they are running Windows They open a DOS window, and their input and output is console mode. There are also some standard Win32 programs that also use the console input and output. If you don't want to use the graphical interface in Win32, you can use allocconsole to get a console, then get the input or output handle via the GetStdHandle, and then use WriteConsole or Writefile to put the result Outputs to the console (usually an icon DOS window). Although these programs look like a DOS program, they are unclosed Win32 programs. If you use it under pure DOS, "The Program Must Run Under Windows!" Is displayed. One console has three handles: standard input, standard output, and standard error handles, standard input, standard output handle can be reordered, you can replace it with anonymous pipeline, so that you can take the other end of the pipe Use another process to receive or enter, and the control desk is not feeling different, just like the> or Standard Output Device (Generally Screen) (Console Process Input) Read <---- Standard Enter Device (Generally Keyboard) After replacing the pipe: (as the console process of the sub-process) Write ----> Pipe 1 ----> Read (Parent Process) (as the console process of the child process) Read <----> The steps of the pipe 2 <---- WRITE (parent process) Using anonymous pipelines are as follows:

Use CreatePipe to create two pipes, get the pipe handle, one is used to input, a process to output ready to perform the control station process, first using getStartupInfo to get StartupInfo with the first pipe handle in STARTUPINFO, HSTDOUT, HSTDERROR , That is, the standard input, output, the error handle uses the CreateProcess execution sub-process, which is established by the sub-process input and output is directed to the parent process in the pipe to read the second pipe through the readfile to obtain the output of the child process, and write the first by Writefile Pipes to write input to child processes, parent processes, can query the sub-process through PeekNameDpipe After the output sub-process is over, turn off two pipes through CloseHandle. The following is a specific description and definition of: 1 using an anonymous pipe CreatePipe following prototype: BOOL CreatePipe (PHANDLE hReadPipe, // address of variable for read handle PHANDLE hWritePipe, // address of variable for write handle LPSECURITY_ATTRIBUTES lpPipeAttributes, // pointer to Security Attributes DWord nsize // Number of Bytes Reserved for Pipe); After the pipe is established, HREADPIPE and HWRITEPIPE pointed to by the structure can be used to read and write the pipeline, of course, because the anonymous pipeline is unidirectional, you can only use one of them. The structure of the security_attributes in the parameter must be filled out, defined as follows: typedef struct_security_attributes {dword NLENGTH: / / Define the length of this structure in bytes LPVOID LPSECURITYDESCRIPTOR; / / Point to control the security descriptor shared by the object if it is NULL Objects will be assigned a default security description Bool BinheritHandle; // Defines whether it returns whether it is inherited when a new process is created.} Security_attributes; 2. Fill in the created sub-process STARTupInfo structure Generally, we can first use GetStartupinfo to fill in a default structure, then change our place to get, they are:

hStdInput - with a conduit wherein hWritePipe instead hStdOutput, hStdError - hReadPipe replaced with another duct dwFlags - STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW set to represent input and output handles wShowWindow wShowWindow field is valid - set SW_HIDE, so that when the subprocess No window is displayed. After filling out, you can use createProcess to perform sub-processes. The specific operation of the execution sub-process can refer to the previous tutorial "Process Control" 3. You can use the peeknamedpipe query sub-process in the program, the original shape is as follows: BOOL PeekNamedPipe (hANDLE hNamedPipe, // handle to pipe to copy from LPVOID lpBuffer, // pointer to data bufferDWORD nBufferSize, // size, in bytes, of data buffer LPDWORD lpBytesRead, // pointer to number of bytes read LPDWORD lpTotalBytesAvail, // Pointer to Total Number Of Bytes Available LPDWORD LPBYTESLEFTTHISMESSAGE / / POINTER TO Unread bytes in this message); we can try to read the NBuffersize size data, then you can get how much data in the pipeline by returning BytesRead, if not equal, if not equal, There is data to be read. 4. Use readfile and writefile to read and write the pipeline, their parameters are exactly the same, the original shape is as follows: Readfile or Writefile (Handle Hfile, // Handle of File To Read Using Pipe Handle LPVOID LPBuffer, // Address Of Buffer That receives data buffer address DWORD nNumberOfBytesToRead, // number of bytes to read the number of bytes read prepared LPDWORD lpNumberOfBytesRead, the number of bytes LPOVERLAPPED lpOverlapped // address of number of bytes read, the actual read or written // address Of structure for data Use null here; 5. Close the four handles of HREADPIPE and HWRITEPIPE with CloseHandle. The following example is given, this program is an extension of the previous tutorial "process control", if you feel strange to some API, please read the previous tutorial. Source program - assembly source file debug EQU 0; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>

PROGRAMMED by Luo Yunbin, Bigluo@telekbird.com.cn

; Website: http://asm.yeah.net

Luoyunbin's Win32 ASM Page (Luo Yunbin's Programming Park)

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

; Version Information

; Assembly test with example - Pipeline example

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.386

.Model flat, stdcall

Option Casemap: None; Case Sensitive

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Include data

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

INCLUDE Windows.inc

INCLUDE User32.inc

INCLUDE KERNEL32.INC

INCLUDE COMCTL32.INC

INCLUDE COMDLG32.INC

INCLUDE GDI32.INC

INCLUDELIB USER32.LIB

IncludeLib kernel32.lib

INCLUDELIB COMCTL32.LIB

INCLUDELIB COMDLG32.LIB

IncludeLib GDI32.LIB

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

ICO_MAIN EQU 1000

MENU_MAIN EQU 2000

IDM_EXEC EQU 2001

IDM_EXIT EQU 2002

F_Running EQU 0001H; Process is in operation

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Data segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA?

StSTARTUP STARTUPINFO

Hinstance DD?

HMENU DD?

HwinMain DD?

HWINTEXT DD?

HFONT DD?

HRUNTHREAD DD?

HREAD1 DD?

HWRITE1 DD?

HREAD2 DD?

HWRITE2 DD?

SZBuffer DB 512 DUP (?)

DWFLAG DD?

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.DATA

Sz Genexecute DB 'Connect MS- & DOS Mode', 0SZEXCUTEERROR DB 'Start application error! ', 0

SZCAPTION DB 'Pipeline sample program ... http://asm.yeah.net' ,0

SzclassName DB 'PIPEEXAMPLE', 0

SZDLNAME DB 'Riched32.dll', 0

Szclassnamered DB 'Richedit', 0

SZDLNAME DB 'Riched20.dll', 0

SzclassNameredit DB 'Richedit20a', 0

SZCommand DB 'c: /command.com' ,0

STLOGFONT LOGFONT <24, 0, 0, FW_NORMAL, /

0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, /

Clip_stroke_precis, default_quality, /

DEFAULT_PITCH or FF_SWISS, "Fixedsys">

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

Code segment

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>

.code

IF Debug

INCLUDE Debug.asm

ENDIF

INCLUDE WIN.ASM

*********************************************************** *******************

Implementing threads used

1. Establish a process with CreateProcess

; 2. Waiting for the process of waiting for the process of WaitforsingleOject

*********************************************************** *******************

_Runthread Proc Uses EBX ECX EDX ESI EDI, /

DWParam: DWORD

Local @stsecurity: Security_Attributes

Local @dwexitcode

Local @dwbytesread

Local @strange: charrange

OR dwflag, f_running

*********************************************************** *******************

"Execute" menu is changed to "end"

*********************************************************** ****************** Invoke EnableMenuItem, HMENU, IDM_EXEC, MF_GRAYED

Invoke EnableMenuItem, HMENU, IDM_EXIT, MF_GRAYED

*********************************************************** *******************

Establish a pipeline

*********************************************************** *******************

Mov @ stsecurity.nlength, sizeof security_attributes, SIZEOF Security_ATINGTH, SIZEOF SECURITY_ATTRIBUTES

Mov @ stsecurity.lpsecurityDescriptor, NULL

Mov @ stsecurity.binherithandle, true

Invoke CreatePipe, AddR Hread1, AddR HWrite1, Addr @ StSecurity, Null

Invoke Cread2, AddR HWRITE2, ADDR @ StSecurity, NULL

*********************************************************** *******************

; Execute file, wait for the end to end if successful

*********************************************************** *******************

Invoke GetStartupinfo, AddR StStartup

Mov Eax, Hread1

Mov StStartup.hstdInput, EAX

Mov Eax, HWRITE2

Mov StStartup.hstdoutput, EAX

Mov StStartup.hstderror, EAX

Mov StStartup.dwflags, Startf_useStdhandles or Startf_useshowWindow

Mov StStartup.WShowWindow, SW_HIDE

Invoke CreateProcess, NULL, AddR Szcommand, Null, NULL, /

NULL, NORMAL_PRIORITY_CLASS, NULL, NULL, OFFSET StStartup, Offset StPROCINFO

.IF EAX! = 0

.While true

Invoke getExitcodeProcess, StProcinfo.hprocess, Addr @dwexitcode

.break .if @dwexitcode! = still_active

Invoke Peeknamedpipe, Hread2, Addr Szbuffer, 511, Addr @ dwbytesread, NULL, NULL

.IF @dwbytesread! = 0

Invoke RTLZERMEMORY, ADDR SZBUFFER, 512

Invoke Readfile, Hread2, AddR Szbuffer, @ dwbytesread, addr @ dwbytesread, null

Mov @ strange.cpmin, -1

Mov @ strange.cpmax, -1

Invoke SendMessage, Hwintext, EM_EXSETSEL, 0, ADDR @StRange

Invoke SendMessage, Hwintext, EM_REPLACESEL, FALSE, ADDR SZBUFFER

Invoke SendMessage, Hwintext, Em_Scrollcaret, Null, Nullinvoke SendMessage, Hwintext, WM_SETFONT, HFONT, 0

.endif

.endw

Invoke CloseHandle, StProcinfo.hprocess

Invoke Closehandle, StProcinfo.hthread

.lse

Invoke Messagebox, Hwinmain, Addr SzexcuteError, NULL, MB_OK OR MB_ICONERROR

.endif

*********************************************************** *******************

Close the pipeline

*********************************************************** *******************

Invoke Closehandle, Hread1

Invoke Closehandle, HWRITE1

Invoke Closehandle, Hread2

Invoke closehandle, hwrite2

*********************************************************** *******************

; Change the "End" menu to "Execute"

*********************************************************** *******************

Invoke EnableMenuItem, HMENU, IDM_EXEC, MF_ENABLED

Invoke EnableMenuItem, HMENU, IDM_EXIT, MF_ENABLED

Invoke EnableWindow, HWINTEXT, FALSE

And dwflag, not f_running

RET

_RunthRead Endp

*********************************************************** *******************

Window program

*********************************************************** *******************

WNDMAINPROC PROC Uses EBX EDI ESI, /

HWND: DWORD, WMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

MOV EAX, WMSG

*********************************************************** *******************

.IF EAX == WM_CREATE

Mov Eax, HWnd

Mov Hwinmain, EAX

Call_init

*********************************************************** *******************

.ELSEIF EAX == WM_SIZE

Mov Edx, LParam

MOV ECX, EDX

SHR ECX, 16

And EDX, 0FFFFH

Invoke MoveWindow, Hwintext, 0, 0, EDX, ECX, True

Invoke Postmessage, Hwintext, WM_SIZE, WPARAM, LPARAM

*********************************************************** *******************

.ELSEIF EAX == WM_Close

Test dwflag, f_running

.IF ZERO?

Invoke DestroyWindow, HwinMain

Invoke PostquitMessage, NULL

.endif

*********************************************************** *******************. Elseif EAX == WM_COMMAND

Mov Eax, WPARAM

.IF AX == idm_exec

*********************************************************** *******************

If the thread is established if not in the execution (dwflag is not set), execute the program in the thread

If it is already in execution, use TerminateProcess to terminate execution

*********************************************************** *******************

Test dwflag, f_running

.IF ZERO?

Invoke EnableWindow, HWINTEXT, TRUE

Invoke setfocus, hwintext

Invoke CreateThread, Null, Null, Offset _Runthread, /

NULL, NULL, OFFSET HRUNTHREAD

.lse

Invoke TerminateProcess, StProcinfo.hprocess, -1

.endif

.ELSEIF AX == IDM_EXIT

Invoke DestroyWindow, HwinMain

Invoke PostquitMessage, NULL

.endif

.lse

Invoke DefWindowProc, Hwnd, WMSG, WPARAM, LPARAM

RET

.endif

XOR EAX, EAX

RET

WNDMAINPROC ENDP

*********************************************************** *******************

Procedure

*********************************************************** *******************

Start:

Call_winmain

Invoke EXITPROCESS, NULL

*********************************************************** *******************

_WinMain Proc

Local @stwcmain: WNDCLASSEX

Local @stmsg: msg

Local @hrichedit

Invoke LoadLibrary, Offset Szdllname

Mov @ hrichedit, EAX

Invoke INITCOMMONCONTROLS

Invoke getModuleHandle, NULL

Mov Hinstance, EAX

Invoke loadmenu, hinstance, menu_main

Mov Hmenu, EAX

**************** Registration window *************************************** **********

Invoke loadCursor, 0, IDC_ARROW

Mov @ stwcmain.hcursor, EAX

Mov @ stwcmain.cbsize, sizeof wndclassex

Mov @ stwcmain.hiconsm, 0

Mov @ stwcmain.style, cs_hredraw or cs_vredraw

Mov @ stwcmain.lpfnwndproc, Offset WNDMAINPROC

Mov @ stwcmain.cbclsextra, 0

Mov @ stwcmain.cbwndextra, 0

Mov Eax, Hinstancemov @ stwcmain.hinstance, EAX

INVOKE LOADICON, HINSTANCE, ICO_MAIN

Mov @ stwcmain.hicon, EAX

Mov @ stwcmain.hbrbackground, color_btnface 1

Mov @ stwcmain.lpszclassname, offset szclassname

Mov @ stwcmain.lpszMenuname, 0

Invoke registerclassex, addr @stwcmain

**************** Establish an output window ************************************** ************

Invoke CreateWindowex, NULL, /

Offset szclassname, offset szcaption, /

WS_OVERLAPPEDWINDOW, /

0, 0, 680, 420, /

NULL, HMENU, HINSTANCE, NULL

Invoke ShowWindow, Hwinmain, SW_SHOWNORMAL

Invoke UpdateWindow, HwinMain

*********************************************************** *******************

.While true

Invoke GetMsg, NULL, 0, 0

.break .if eax == 0

Invoke TranslateMsg, Addr @stmsg

Invoke DispatchMessage, Addr @STMSG

.endw

Invoke freelibrary, @ hrichedit

Invoke deleteObject, HFONT

RET

_WinMain ENDP

*********************************************************** *******************

Input program

*********************************************************** *******************

_INPUTPROC PROC Uses EBX EDI ESI, /

HWnd: DWORD, UMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

Local @szbuffer [4]: ​​Byte

Local @dwbyteswrite

MOV EAX, UMSG

.IF EAX == WM_CHAR

Mov Eax, WPARAM

Movzx Eax, Al

Mov DWord PTR @ SZBuffer, EAX

Test dwflag, f_running

.IF! ZERO?

Invoke Writefile, Hwrite1, Addr @ Szbuffer, 1, Addr @ dwbyteswrite, null

.endif

XOR EAX, EAX

RET

.endif

Invoke GetWindowlong, HWnd, GWL_USERDATA

Invoke CallWindowProc, EAX, HWND, UMSG, WPARAM, LPARAM

RET

_Inputproc ENDP

*********************************************************** *******************

_Init proc

*************** Establish an output RicheDit window ************************************** *****

Invoke CreateWindowex, WS_EX_CLIENTEDGE, OFFSET SZCLASSNAMEREDIT, / NULL, WS_CHILD OR WS_VISible or WS_VSCROLL OR WS_HSCROLL /

OR ES_MULTILINE OR ES_AUTOHSCROLL OR ES_AUTOVSCROLL, /

0, 0, 0, 0, /

Hwinmain, Null, Hinstance, Null

Mov Hwintext, EAX

*************** Set font *************************************** ****************

Invoke CreateFontIndirect, Offset Stlogfont

MOV HFONT, EAX

Invoke SendMessage, Hwintext, WM_SETFONT, HFONT, 0

Invoke SendMessage, Hwintext, EM_SETREADONLY, TRUE, NULL

Invoke setWindowlong, Hwintext, GWL_WndProc, Offset _inputproc

Invoke SetWindowlong, Hwintext, GWL_USERDATA, EAX

Invoke EnableWindow, HWINTEXT, FALSE

Invoke _CenterWindow, HwinMain

Invoke setfocus, hwintext

RET

_Init ENDP

*********************************************************** *******************

End Start

The program analyzes and points in the program, I first established a RicheDit control to display the output of the sub-process, while using the RicheDit subclass, intercepting its keyboard input to send it to the child process invoke setwindowlong, hwintext, gwl_wndproc, Offset _inputproc This statement refers to the _inputproc process, then in the _inputproc WM_CHAR, I will build two pipes in the program, then implement C: /command.com. This gives a DOS command line process, and then there is no output through the PeeknameDpipe detection sub-process in the loop. If any, readfile is read in the RicheDit. Be careful when running an example, you can perform almost all other programs in this "command.com", but do not perform programs such as UCDOS, PCTools, and programs that do not use standard input output (not used in DOS) ">" Or "<" redirected procedure), because we used WS_HIDE when we loaded the process, the original command.com's window is hidden. If you perform this program, it means you lose The control of the sub-process, because they do not use standard input to receive the keyboard, you can't get them from the pipeline. Here you can also quote another usage of anonymous pipes. If you don't have command.com but similar to the arj.exe program, then you don't have to display its output into the Richedit, but in the program, So, you can write a Winarj, of course, you only need to write a window interface and the cooperation between Arj.exe. 13. Operation Operation Operation Operating Overview of the program is often used in the program to set or other small amount of data, so that the program can be used when executed next time, such as the location, size, some user settings of the window, and some users set. Data, etc., when programmed under DOS, we generally produce a file, write these data to the file, and then read it again in the next execution. In Win32 programming, you can also do this, but Windows has provided us with two convenient methods, which is to save a small amount of data using the registry or INI file (Profile). This article first introduces the use of .ini files. The INI file is the text file, the middle data format is generally: [section1 name] keyname1 = value1keyname2 = value1 = value1key = value1 = value1keyname2 = value2ini file can be divided into several sections, each section name is used [] It is enclosed in a section, there can be many keys, each Key can have a value and occupy a row, the format is key = value, Win32's API for the INI file operation, is a part of Win.ini, Part is part of the user-defined INI file operation. Win.IN and System.ini are two very important initialization files of Windows, and Windows records the selection made by the user and various changes in the system information in these two files. System.ini describes the current state of the system hardware, and the Win.ini file contains the current configuration of the Windows system running environment.

Due to the importance and commonality of Win.ini files, Win32 has an API that operates in Win.ini, which is: getProfileint - get a key value from a section of the win.ini file, its original shape is : GetProfileint (LPCTSTR LPAPPNAME, "pointing to the string address containing the section name LPCTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTOTER ST NDEFAULT // If the key value is not found, if the key value is not found, if it returns the default value); if If the key value is not found, the return value is the default value specified by nDefault. If the value in the key is negative, it returns 0, if the key specifies the mixing of the numbers and strings, returns the value of the digital portion, such as X = 1234ABCD, returns 1234GetProfileString - get a key string from a section of the win.ini file, its original shape is: getProfileString (LPCTSTR LPAPPNAME, point to the string address containing the section name LPCTSTSTR LPKEYNAME, / / ​​Point to include address LPCTSTR lpDefault Key string name, // If a Key value is not found, then the address LPTSTR lpReturnedString return the default string, the address string // return the buffer length of the buffer DWORD nSize //); return In the buffer, the returned EAX value is the length of the returned string (0) GetProfileeSection - reads the entire section from the win.ini file, its original shape is: getProfilesection (LPCTSTR LPAPPNAME, / / Points to the string address of the SECTION name, LPTSTR LPRETURNEDSTRING, / / ​​Return data buffer address DWORD nsize // Return the buffer length of the data); WriteProfileSection - Write the value of the entire section to the specified section of the Win.ini file Section In, its original shape is: WriteProfileSection (lpctstr lpappname, // pointing to string address containing the section name LPCTS Tr lpstring // The address of the data to be written); if Win.ini does not specify the section, the API will create a newly established and write data. If it already exists, first remove all the key in the original Secit, and write new of. WriteProfileString - Write a Key value in the specified section of the Win.ini file, its original shape is: WriteProfileString (LPCTSTR LPAPPNAME, // Point to the string address lpctstr lpkeyName containing the section name, // Point to the string address containing the KEY name LPCTSTSTR LPSTRING // The string address to be written; if Win.ini does not have the specified section, the API will create a new section. If there is no specified key, create a new key and write data, if already existing, use the string instead of the original Value.

The above API is working for Win.ini. Of course, for us, more is to build your own INI file in the directory running, if you need to operate your own INI file, you will use another Group API, this set of APIs and tops, as long as the above set of Profile can be replaced with privateprofile (private), the parameters of an INI file name are also corresponding to the parameters. For example GetPrivateProfileInt, GetPrivateProfileSection, WritePrivateProfileString the like, the following were introduced: GetPrivateProfileInt - obtaining a key from a file INI Section integer value, which is the prototype: GetPrivateProfileInt (LPCTSTR lpAppName, // Section to a string containing the name of the address LPCTSTR LPKEYNAME, / / ​​Point to the string address containing the key name INT ndefault // If the key value is not found, the default value is the file name of the LPCTSTR LPFILENAME // INI file); the definition of the middle parameter and the return value and getProfileint it's the same. GetPrivateProfileString - gets a key string from a section of the INI file, its original shape is: getPrivateProfileString (LPCTSTR LPAPPNAME, "pointing to a string address lpctstr lpkeyName containing the section name, // Point to the string address containing the KEY name LPCTSTR LPDEFAULT, // If the key value is not found, the default string is returned LPTSTR LPRETURNEDSTRING, / / ​​Returns the buffer address of the buffer address DWORD nsize // Buffer LPCTSTSTR LPFILENAME // INI file name); GetPrivateProfileSECTION - Reads the entire section from the INI file, its original shape is: getPrivateProfileSection (LPCTSTR LPAPPNAME, "pointing to a string address containing the section name LPTSTSTSTSTSTSTSTSTSTSTURTURNEDSTRING, / / ​​Return data buffer address DWORD nsize // Return data The file name of the buffer length LPCTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTSTATIONS: This API can read the entire section, when you don't know which Key is in section, you can use this API to read the entire section and then processed.

GetPrivateProfileSectionNames - Section obtained from the ini file name, which is the prototype: GetPrivateProfileSectionNames (LPTSTR lpszReturnBuffer, // return the data buffer addresses DWORD nSize // returned data buffer length LPCTSTR lpFileName // ini file of the file name); If there are two sections: [Sec1] and [SEC2] in INI, the return is 'Sec1', 0, 'SEC2', 0, 0, when you don't know what sections in INI, you can use this API. Get Name WritePrivateProfileSECTION - In specifying the content of the entire section, its original shape is: WritePrivateProfileSection (LPCTSTR LPAPPNAME) (LPCTSTSTR LPAPPNAME, "pointing to the address of the string address containing the section name LPCTSTSTSTSTSTSTSTSTSTSTR LPFileName // INI file name); WritePrivateProfileString - WritePrivateProfileString - Write a key value in the specified section of the INI file, its original shape is: WritePrivateProfileString (lpctstr lpappname, // point to the string address containing the section name LPCTSTSTR LPKEYNAME, // Pointing the file name of the string address lpctstr lpstring // to be written by the string address of the key name); if there is no section in INI, the API will create new sections, if not the specified key, create a new one Key and write data, if it already exists, use a string instead of the original value. When the specified INI does not exist, the API automatically creates a new file, so the benefit of using INI is that we don't have to save a small amount of data involved in file operations, even if you don't have the operation where you exist if you find the file. Using the point: When we actually use, getPrivateProfileString and WritePrivateProfileString, but should pay attention to when the INI file is active, if the file specified by the LPFileName does not have a path, the API will go to Windows installation directory. Going to find it in the current directory, but every time II functions are used to get the current path. It is obviously too much trouble. Here is a variety of ways, you only need to add it in front of the INI file name. / Other To operate the user.ini in this directory, then the file name is './user.ini' This is obviously more convenient. In addition, when you want to clear a key clear, you can use the lpstring to point to an empty string and use WritePrivateProfileString. When you want to clear all the contents of a section, you don't have to clear your KEY one by one, you can use the lpstring to point to an empty string and then use WritePrivateProfilesection.

14.WIN32ASM experience bit Q1. How to hide / display the taskbar? Q2. How to disable / allow / display / hide the start button? Q3. How to create a real "always on the top" window? Q4. How to create a hotkey? CTRL Alt A Q5. How to get a Windows directory and system directory? Q6. How to open the start menu from my program? Q7. How to close the active program? Q8. How to remove the window title? Q9. How to know if the window is Taskbar (or visible)? Q10. How to hide a window? Q11. How to place the window in the front desk? Q12. How to block Ctrl Alt Del, Alt Tab Ctrl ESC These keys? Q13. How to determine the Windows task Is the automatic hidden feature of the column to be activated? Q14. How to use the default browser or mail program? Q15. How to use Win32 API to display the network connection dialog box? - How to hide / display the taskbar? Shell DB "shell_trayWnd", 0; task Class name Invoke Findow, addr shell, null; first get the handle, then hide. ..F eax! = 0invoke showwindow, eax, sw_hide; display .enDif with sw_show.

- How to prohibit / allow / display / hide start button?. Data? Buffer DB 127 DUP (?). Datashell DB "shell_traywnd", 0sbar DB "Button, 0Child DD? Slen DD? CodeInvoke FindWindow, AddR shell, NULL; Get the status bar handle MOV TRAY, EAXINVOKE GETWINDOW, TRAY, GW_CHILD; get the child window (if any) Mov Child, Eax.if CHild! = 0invoke getclassname, child, offset buffer, sizeof buffer; get sub-window classes Name .IF EAX> 0INVoke Lstrlen, Offset Buffer; Get Class Name Length Mov Slen, EaxInvoke CharupperBuff, Offset Buffer, Slen; Transformer INVOKE LSTRCMP, ADDR BUFFER, ADDR SBAR; Compare class name with 'Button'. IF EAX = = 0invoke ShowWindow, child, SW_HIDE; hide the start button; invoke ShowWindow, child, SW_SHOW; display the start button; invoke EnableWindow, child, FALSE; prohibit the start button; invoke EnableWindow, child, TRUE; allowing the start button .endif .endif.endif

- How to create a real "always on the top" window? Invoke SetWindowPos, HWIN, HWND_TOPMOST, NULL, NULL, NULL, NULL, SWP_NOACTIVATE OR SWP_NOMOVE OR SWP_NOSIZE

- How to create hot keys? Such as Ctrl Alt a .DataHMSG DB "Hotkey Ctrl Alt a Works Good!", 0hcap DB "Hotkey Example", 0.code.if umsg == WM_CREATEINVOKE Registerhotkey, HWnd, 065H, MOD_CONTROL or MOD_ALT, 041h; CTRL ALT A (041h is 65 - 065h is 101) .elseif uMsg == WM_HOTKEYinvoke MessageBox, hWin, addr hmsg, addr hcap, MB_OK or MB_ICONINFORMATION.elseif uMsg == WM_DESTROYinvoke UnregisterHotKey, hWin, 065hinvoke PostQuitMessage , NULLreturn 0 .endif- how to obtain the Windows directory and system directory .databuffer db 50 dup hCap db "WindowsDirectory", 0.codeinvoke GetWindowsDirectory, addr buffer, sizeof buffer (?); Windows home directory in the buffer; invoke GetSystemDirectory, addr Buffer, Sizeof Buffer; Settings System Directory in Buffer Invoke MessageBox, HWnd, AddR Buffer, Addr Hcap, MB_OK or MB_ICONITIONMATION

How do I open the start menu from my program? Invoke SendMessage, Hwnd, WM_SYSCOMMAND, SC_TASKLIST, NULL

- How to close the activated program? .Datafwin Dd? .Codeinvoke getforegroundwindowmov Fwin, EaxInvoke SendMessage, Fwin, WM_Close, Null

- How to get off the window title? Invoke getWindowlong, hwnd, gwl_style; get the current window and Eax, not ws_caption; remove WS_CAPTIONINVOKE SETWINDOWLONG, HWND, GWL_STYLE, EAX; Settings window classes

- How do you know if the window is in the task bar (or visible)? Invoke iswindowvisible, hwin.if eax == true; window visible .Elese; window is invisible .enDif

- How to hide a window? DataMirc DB "mirc32", 0MHand Dd? .Codeinvoke FindWindow, Addr mirc, null; looking for mirc32mov mhand, eax .IF MHAND! = 0; found? Invoke ShowWindow, Mhand, SW_SHOW; Display Window; Invoke ShowWindow, MHAND, SW_HIDE; hidden window. ELSE; mirc32 is not running .... Endif

- How to place the window in front? Invoke setForegroundWindow, MHAND

How to Shield Ctrl Alt Del, Alt Tab Ctrl ESC These keys? Invoke SystemParametersInfo, SPI_Screensaverrunning, 1, Null, NULL; Windows98 Only 1 Off 0 Allow

- How to determine whether the auto-hide feature of Windows task bar is activated .dataAppBar APPBARDATA {}; {} refers to the use of default values ​​... Thanks to TTom.codemov AppBar.cbSize, sizeof AppBarinvoke SHAppBarMessage, ABM_GETSTATE, addr AppBar; ShellApi command and? Eax, ABS_AUTOHIDE.IF EAX == True; Taskbar is hidden .Else; Task Bar is not hidden. Nendif - How to use the default browser or mail program? Datalppage DB "http://win32asm.cjb.net", 0lpMail db "ates@anet.net.tr", 0lpOperation db "open", 0.codeinvoke ShellExecute, hWin, addr lpOperation, addr lpPage, NULL, NULL, SW_SHOWNORMALinvoke ShellExecute, hWin, addr lpOperation, addr lpMail, NULL, NULL, SW_SHOWNORMAL

- How to display network connection dialog box with Win32 API? Include /masm32/include/mpr.incincludelib /masm32/lib/mpr.libinvoke WnetConnectionDialog, hwnd, resourcetype_disk

Designed by Atilla Yurtseven Chinese Translation by Orochi, 2000.12.16

转载请注明原文地址:https://www.9cbs.com/read-79125.html

New Post(0)