2-6

backprnt.c
/*
 * BackPrnt.c
 *
 * Sample code for "Multithreading Applications in Win32"
 * This is from Chapter 2, Listing 2-6
 *
 * Demonstrates background printing
 
*/

#define  WIN32_LEAN_AND_MEAN
#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< windows.h >
#include 
< windowsx.h >
#include 
< commdlg.h >
#include 
" resource.h "
#include 
" MtVerify.h "

//
//  Macro definitions
//
#define  WM_SHOWBITMAP   WM_APP

#define  MAX_PRINT_JOBS  64


//
//  Structures
//
typedef  struct
{   
//  Information passed to background thread for printing
    HWND hDlg;
    HWND hWndParent;
    HDC hDc;
    BOOL bPrint;    
//  TRUE if printing;
     char  szText[ 256 ];
} ThreadPrintInfo;

//
//  Global variables
//
HANDLE hInst;
HBITMAP gbmpDisplay;
RECT gDisplayRect;

int  gNumPrinting  =   0 ;

//  Handle to each created thread
HANDLE gPrintJobs[ 64 ];

//  Height of bitmap returned by DrawText
int  iHeight;

//  HWND of the dialog so other threads can find it.
HWND hDlgMain;


//
//  Function declarations
//
int  APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,  int  nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hWnd, unsigned msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK PrintDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL PrintDlg_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam);
void  PrintDlg_OnCommand(HWND hDlg,  int  id, HWND hwndCtl, UINT codeNotify);
void  PrintDlg_OnPaint(HWND hwnd);
void  PrintText(HWND hwndParent,  char   * pszText);
void  PrintToDisplay(HWND hwndParent,  char   * pszText);
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
DWORD WINAPI BackgroundPrintThread(LPVOID pVoid);


///////////////////////////////////////////////////////// //
//
//       WinMain
//
//  Main entry point of application. This will be a
//  dialog based app, not a normal window, so this
//  routine acts a little differently than "normal".
//
int  APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,  int  nCmdShow)
{
    MSG     msg;
    HWND    hWnd;
    WNDCLASS wc;
    
int  index;

    hInst 
=  hInstance;
    
if  ( ! hPrevInstance)
    {
        memset(
& wc,  0 sizeof (wc));
        wc.lpfnWndProc  
=  MainWndProc;
        wc.hInstance    
=  hInstance;
        wc.hIcon        
=  LoadIcon (hInstance,  " GenIco " );
        wc.hCursor      
=  LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground
=  GetSysColorBrush(COLOR_BACKGROUND);
        wc.lpszMenuName 
=   " PRINTING_MENU " ;
        wc.lpszClassName
=   " PrintDlgClass " ;
        
if  ( ! RegisterClass( & wc))
            
return  FALSE;
    }


    hWnd 
=  CreateWindow(
        
" PrintDlgClass " ,
        
" Background Printing " ,
        WS_OVERLAPPED
| WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
        CW_USEDEFAULT, 
//  At this point we do not want to
         0 ,              //   show the window until we know
         0 ,              //   how big the Dialog Box is so
         0 ,              //   that we can fit the main window
        NULL,           //   around it.
        NULL,
        hInstance,
        NULL);

    hDlgMain 
=  CreateDialog(hInst,
                    MAKEINTRESOURCE(IDD_PRINT),
                    hWnd, PrintDlgProc);

    ShowWindow(hWnd, nCmdShow);
    ShowWindow(hDlgMain, SW_SHOW);

    
while  (GetMessage( & msg, NULL,  0 0 ))
    {    
//  Get Next message in queue
         if (hDlgMain  ==  NULL  ||   ! IsDialogMessage(hDlgMain, & msg))
        {
            TranslateMessage(
& msg);  /*  Translate virtual key codes  */
            DispatchMessage(
& msg);     /*  Dispatches message to window  */
        }
    } 
//  end while

    
//  Wait for all threads to terminate. The Window will
    
//  have already disappeared by this point.
     for  (index  =   0 ; index  <  gNumPrinting; index ++ )
    {
        DWORD status;
        
do  
        {    
//  Wait for thread to terminate
            GetExitCodeThread(gPrintJobs[index],  & status);
            Sleep(
10 );
        } 
while  (status  ==  STILL_ACTIVE);

    } 
//  end for

    
return  (msg.wParam);   /*  Returns the value from PostQuitMessage  */
}


LRESULT CALLBACK MainWndProc(HWND hWnd, unsigned msg, WPARAM wParam, LPARAM lParam)
{
    
switch  (msg)
    {
    
case  WM_CREATE:
        
break ;

    
case  WM_COMMAND:

        
switch  (wParam)
        {
        
case  IDM_ABOUT:
            DialogBox(hInst, 
" AboutBox " , hWnd, (DLGPROC)About);
            
break ;
        
case  IDM_EXIT:
            PostQuitMessage(
0 );
            
break ;
        
default :
            
return  (DefWindowProc(hWnd, msg, wParam, lParam));
        }

    
case  WM_SETFOCUS:
        
//  ensure that the Dialog Box has the focus
        SetFocus(hDlgMain);
        
break ;

    
case  WM_DESTROY:
        PostQuitMessage(
0 );
        
break ;

    
default :
        
return  DefWindowProc(hWnd, msg, wParam, lParam);

    }
    
return   0 ;
}


LRESULT CALLBACK PrintDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    
switch  (uMsg)
    {
    
case  WM_CLOSE:
        DestroyWindow(hDlg);
        hDlgMain 
=  NULL;
        
break ;
        
    
case  WM_DESTROY:
        
return  TRUE;
        
break ;

    
case  WM_SHOWBITMAP:
        
if  (gbmpDisplay)
            DeleteObject(gbmpDisplay);

        gDisplayRect 
=   * (RECT * )wParam;
        gbmpDisplay 
=  (HBITMAP) lParam;
        InvalidateRect(hDlgMain, NULL, TRUE);
        
break ;

    HANDLE_MSG(hDlg, WM_INITDIALOG, PrintDlg_OnInitDialog);
    HANDLE_MSG(hDlg, WM_COMMAND, PrintDlg_OnCommand);
    HANDLE_MSG(hDlg, WM_PAINT, PrintDlg_OnPaint);

    
default :
        
return  (FALSE);
    }

    
return   0 ;
}

BOOL PrintDlg_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam)
{
    RECT rect;

    
//  Size parent to fit this dialog
    GetWindowRect(hwndDlg,  & rect); 
    SetWindowPos(GetParent(hwndDlg),NULL,
        
0 , 0 ,
        rect.right
- rect.left,
        rect.bottom
- rect.top + GetSystemMetrics(SM_CYMENU)
            
+ GetSystemMetrics(SM_CYCAPTION),
        SWP_NOMOVE 
|  SWP_NOZORDER);

    
return  TRUE;
}

void  PrintDlg_OnCommand(HWND hDlg,  int  id,HWND hwndCtl, UINT codeNotify)
{
    
char  szText[ 256 ];

    
switch  (id)
    {
    
case  IDC_PRINT:
        GetDlgItemText(hDlg, IDC_EDIT_TEXT, szText, 
256 );
        PrintText(hDlg, szText);
        
break ;

    
case  IDC_DISPLAY:
        GetDlgItemText(hDlg, IDC_EDIT_TEXT, szText, 
256 );
        PrintToDisplay(hDlg, szText);
        
break ;

    
case  IDCANCEL:
    
case  IDM_EXIT:
        PostMessage(GetParent(hDlg),WM_DESTROY,
                        (WPARAM)
0 , (LPARAM) 0 );
        DestroyWindow(hDlgMain);
        hDlgMain 
=  NULL;
        
break ;
        
    
default :
        
break ;
    }
}

void  PrintDlg_OnPaint( HWND hwnd )
{
    PAINTSTRUCT paint;
    HWND hwndCtrl;
    HDC hdc;
    HDC hDcMem;
    HBITMAP bmpOld;
    RECT rect;
    POINT point;

    
if  ( ! gbmpDisplay)
        
return ;

    hwndCtrl 
=  GetDlgItem(hwnd, IDC_OUTPUT);

    hdc 
=  BeginPaint(hwnd,  & paint);

    GetWindowRect(hwndCtrl, 
& rect);
    point 
=   * ((POINT  * ) & rect);
    ScreenToClient(hwnd, 
& point);

    hDcMem 
=  CreateCompatibleDC(NULL);
    bmpOld 
=  SelectObject(hDcMem, gbmpDisplay);

    
//  Copy bitmap to screen
    MTVERIFY( BitBlt(hdc, point.x + 10 , point.y + 40 ,
        gDisplayRect.right
- gDisplayRect.left, gDisplayRect.bottom - gDisplayRect.top,
        hDcMem, iHeight, 
0 , SRCCOPY) );

    SelectObject(hDcMem, bmpOld);
    DeleteDC(hDcMem);

    EndPaint(hwnd, 
& paint);
}

//
//  Asks user which printer to use, then creates
//  background printing thread.
//
void  PrintText(HWND hwndParent,  char   * pszText)
{
    ThreadPrintInfo 
* pInfo;
    HANDLE hThread;
    DWORD dwThreadId;
    
int  result;
    DOCINFO docInfo;

    PRINTDLG dlgPrint;

    
//  Put up Common Dialog for Printing and get hDC.
    memset( & dlgPrint,  0 sizeof (PRINTDLG));
    dlgPrint.lStructSize 
=   sizeof (PRINTDLG);
    dlgPrint.hwndOwner 
=  hwndParent;
    dlgPrint.Flags 
=  PD_ALLPAGES  |  PD_USEDEVMODECOPIES
           
|  PD_NOPAGENUMS  |  PD_NOSELECTION  |  PD_RETURNDC;
    dlgPrint.hInstance 
=  hInst;
    
if  ( ! PrintDlg( & dlgPrint))
        
return ;

    
//  Initialize Printer device
    docInfo.cbSize  =   sizeof (DOCINFO);
    docInfo.lpszDocName 
=   " Background Printing Example " ;
    docInfo.lpszOutput 
=  NULL;
    docInfo.lpszDatatype 
=  NULL;
    docInfo.fwType 
=   0 ;
    result 
=  StartDoc(dlgPrint.hDC,  & docInfo);
    result 
=  StartPage(dlgPrint.hDC);

    pInfo 
=  HeapAlloc(GetProcessHeap(),
                      HEAP_ZERO_MEMORY,
                      
sizeof (ThreadPrintInfo));
    pInfo
-> hDlg  =  hwndParent;
    pInfo
-> hWndParent  =  hwndParent;
    pInfo
-> hDc  =  dlgPrint.hDC;
    pInfo
-> bPrint  =  TRUE;
    strcpy(pInfo
-> szText, pszText);

    MTVERIFY( hThread 
=  CreateThread(NULL,  0 ,
        BackgroundPrintThread, (LPVOID)pInfo,
        
0 & dwThreadId ));

    
//  keep track of all background printing threads
    gPrintJobs[gNumPrinting ++ =  hThread;
}

//
//  Shows output on the dialog box.
//
void  PrintToDisplay(HWND hwndParent,  char   * pszText)
{
    ThreadPrintInfo 
* pInfo;
    DWORD dwThreadId;
    HANDLE hThread;

    pInfo 
=  HeapAlloc(GetProcessHeap(),
                      HEAP_ZERO_MEMORY,
                      
sizeof (ThreadPrintInfo));
    pInfo
-> hDlg  =  hwndParent;
    pInfo
-> hWndParent  =  GetDlgItem(hwndParent, IDC_OUTPUT);
    pInfo
-> hDc  =  GetDC(pInfo -> hWndParent);
    pInfo
-> bPrint  =  FALSE;
    strcpy(pInfo
-> szText, pszText);

    MTVERIFY( hThread 
=  CreateThread(NULL,  0 ,
                                     BackgroundPrintThread,
                                     (LPVOID)pInfo,
                                     
0 & dwThreadId ));

    
//  keep track of all background printing threads
    gPrintJobs[gNumPrinting ++ =  hThread;
}



// ---------------------------------------------------------
//  About Box Handling
// ---------------------------------------------------------

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
switch  (message) {
        
case  WM_COMMAND:
            
if  (LOWORD(wParam)  ==  IDOK
                
||  LOWORD(wParam)  ==  IDCANCEL)
            {
                EndDialog(hDlg, TRUE);
                
return  (TRUE);
            }
            
break ;

        
default :
            
return  (DefWindowProc(hDlg, message, wParam, lParam));
    }

    
return  FALSE;
}


// ---------------------------------------------------------
//  Background Printing Code
// ---------------------------------------------------------

DWORD WINAPI BackgroundPrintThread(LPVOID pVoid)
{
    ThreadPrintInfo 
* pInfo  =  (ThreadPrintInfo * ) pVoid; 
    RECT rect;
    RECT rectMem;
    HDC hDcMem;
    HBITMAP bmpMem;
    HBITMAP bmpOld;
    
int  x, y;
    
int  counter  =   0 ;
    
int  nHeight;
    HFONT hFont;
    HFONT hFontOld;

    
//  Get dimensions of paper into rect
    rect.left  =   0 ;
    rect.top 
=   0 ;
    rect.right 
=   GetDeviceCaps(pInfo -> hDc, HORZRES);
    rect.bottom 
=  GetDeviceCaps(pInfo -> hDc, VERTRES);

    nHeight 
=   - MulDiv( 36 , GetDeviceCaps(pInfo -> hDc, LOGPIXELSY),  72 );

    
//  Create Font
    hFont  =  CreateFont(nHeight,  0
        
0 0 , FW_DONTCARE, 
        FALSE, FALSE, FALSE, 
        ANSI_CHARSET, 
        OUT_TT_PRECIS, 
        CLIP_DEFAULT_PRECIS,
        PROOF_QUALITY, 
        VARIABLE_PITCH,
        NULL);
    MTASSERT( hFont 
!=   0 );

    
//  Draw into memory device context
    hDcMem  =  CreateCompatibleDC(pInfo -> hDc);
    hFontOld 
=  SelectObject(hDcMem, hFont);
    iHeight 
=  DrawText(hDcMem, pInfo -> szText,  - 1 ,   & rect, DT_LEFT  |  DT_NOPREFIX  |  DT_WORDBREAK  |  DT_CALCRECT);
    rectMem 
=  rect;
    rectMem.left 
=  rect.left  +  iHeight;
    rectMem.right 
=  rect.right  +  (iHeight * 2 );
    bmpMem 
=  CreateCompatibleBitmap(hDcMem,
                                    rectMem.right, rect.bottom);
    bmpOld 
=  SelectObject(hDcMem, bmpMem);
    OffsetRect(
& rect, iHeight,  0 ); 
    DrawText(hDcMem, pInfo
-> szText,  - 1 ,   & rect,
             DT_LEFT 
|  DT_NOPREFIX  |  DT_WORDBREAK);

    
//  Italicize bitmap. We use GetPixel and
    
//  SetPixel because they are horribly inefficient,
    
//  thereby causing the thread to run for awhile.
     for  (y  =   0 ; y  <  iHeight; y ++ )
    {   
//  Italicize line y
         for  (x  =  rectMem.right; x  >  iHeight; x -- )
        {   
//  Move specified pixel to the right.
            COLORREF color;
            
int  offset;
            offset 
=  y  -  iHeight;
            color 
=  GetPixel(hDcMem, x  +  offset, y);
            
if  (color  !=   0 )
                counter
++ ;
            SetPixel(hDcMem, x, y, color);
        } 
//  end for x
    }  //  end for y
    MTASSERT( counter  >   0 );

    
//  Copy bitmap of italicized text from memory to device
     if  (pInfo -> bPrint)
    {
        BitBlt(pInfo
-> hDc,  50 50 , rectMem.right - rect.left, rectMem.bottom - rect.top,
            hDcMem, iHeight, 
0 , SRCCOPY);
    }

    SelectObject(hDcMem, hFontOld);
    SelectObject(hDcMem, bmpOld);
    DeleteDC(hDcMem);

    
if  ( ! pInfo -> bPrint)
    {
        
//  We can't just write to the global variable where the
        
//  bitmap is kept or we might overwrite the work of
        
//  another thread, thereby "losing" a bitmap

        
//  Also, if we used PostMessage instead of SendMessage, then
        
//  the rectangle could have been deleted (it's on the stack)
        
//  by the time the main message loop is reached.
        SendMessage(pInfo -> hDlg, WM_SHOWBITMAP, (WPARAM) & rectMem, (LPARAM) bmpMem);
    }

    
if  (pInfo -> bPrint)
    {   
//  Finish printing
         int  result;

        result 
=  EndPage(pInfo -> hDc);
        MTASSERT (result 
!=  SP_ERROR);
        result 
=  EndDoc(pInfo -> hDc);
        MTASSERT (result 
!=  SP_ERROR);
        DeleteDC(pInfo
-> hDc);
        
//  If we are printing, we are done with the bitmap.
        DeleteObject(bmpMem);
    } 
    
else
    {
        ReleaseDC(pInfo
-> hWndParent, pInfo -> hDc);
    }

    
//  free data structure passed in.
    HeapFree(GetProcessHeap(),  0 , pInfo);

    
return   0 ;
}

od

display

 

004014A0  /$  A1 20994000   mov     eax, dword ptr [409920]
004014A5  |.  81EC 60020000 sub     esp, 260
004014AB  |.  85C0          test    eax, eax
004014AD  |.  55            push    ebp
004014AE  |.  56            push    esi
004014AF  |.  57            push    edi
004014B0  |.  0F84 48010000 je      004015FE
004014B6  |.  8BBC24 700200>mov     edi, dword ptr [esp+270]
004014BD  |.  53            push    ebx
004014BE  |.  68 E9030000   push    3E9                              ; /ControlID = 3E9 (1001.)
004014C3  |.  57            push    edi                              ; |hWnd
004014C4  |.  FF15 14614000 call    dword ptr [<&USER32.GetDlgItem>] ; \GetDlgItem
004014CA  |.  8BF0          mov     esi, eax
004014CC  |.  8D4424 2C     lea     eax, dword ptr [esp+2C]
004014D0  |.  50            push    eax                              ; /pPaintstruct
004014D1  |.  57            push    edi                              ; |hWnd
004014D2  |.  FF15 18614000 call    dword ptr [<&USER32.BeginPaint>] ; \BeginPaint
004014D8  |.  8D4C24 1C     lea     ecx, dword ptr [esp+1C]
004014DC  |.  8BD8          mov     ebx, eax
004014DE  |.  51            push    ecx                              ; /pRect
004014DF  |.  56            push    esi                              ; |hWnd
004014E0  |.  FF15 34614000 call    dword ptr [<&USER32.GetWindowRec>; \GetWindowRect
004014E6  |.  8B5424 1C     mov     edx, dword ptr [esp+1C]
004014EA  |.  8B4424 20     mov     eax, dword ptr [esp+20]
004014EE  |.  8D4C24 14     lea     ecx, dword ptr [esp+14]
004014F2  |.  895424 14     mov     dword ptr [esp+14], edx
004014F6  |.  51            push    ecx                              ; /pPoint
004014F7  |.  57            push    edi                              ; |hWnd
004014F8  |.  894424 20     mov     dword ptr [esp+20], eax          ; |
004014FC  |.  FF15 1C614000 call    dword ptr [<&USER32.ScreenToClie>; \ScreenToClient
00401502  |.  6A 00         push    0                                ; /hDC = NULL
00401504  |.  FF15 24604000 call    dword ptr [<&GDI32.CreateCompati>; \CreateCompatibleDC
0040150A  |.  8B15 20994000 mov     edx, dword ptr [409920]
00401510  |.  8B2D 00604000 mov     ebp, dword ptr [<&GDI32.SelectOb>;  GDI32.SelectObject
00401516  |.  8BF0          mov     esi, eax
00401518  |.  52            push    edx                              ; /hObject => 7F050631
00401519  |.  56            push    esi                              ; |hDC
0040151A  |.  FFD5          call    ebp                              ; \SelectObject
0040151C  |.  8B0D 1C984000 mov     ecx, dword ptr [40981C]
00401522  |.  894424 10     mov     dword ptr [esp+10], eax
00401526  |.  A1 2C994000   mov     eax, dword ptr [40992C]
0040152B  |.  68 2000CC00   push    0CC0020                          ; /ROP = SRCCOPY
00401530  |.  8B15 18984000 mov     edx, dword ptr [409818]          ; |
00401536  |.  6A 00         push    0                                ; |YSrc = 0
00401538  |.  50            push    eax                              ; |XSrc => 37 (55.)
00401539  |.  A1 14984000   mov     eax, dword ptr [409814]          ; |
0040153E  |.  2BC8          sub     ecx, eax                         ; |
00401540  |.  8B4424 24     mov     eax, dword ptr [esp+24]          ; |
00401544  |.  56            push    esi                              ; |hSrcDC
00401545  |.  51            push    ecx                              ; |Height
00401546  |.  8B0D 10984000 mov     ecx, dword ptr [409810]          ; |
0040154C  |.  83C0 28       add     eax, 28                          ; |
0040154F  |.  2BD1          sub     edx, ecx                         ; |
00401551  |.  8B4C24 28     mov     ecx, dword ptr [esp+28]          ; |
00401555  |.  52            push    edx                              ; |Width
00401556  |.  83C1 0A       add     ecx, 0A                          ; |
00401559  |.  50            push    eax                              ; |YDest
0040155A  |.  51            push    ecx                              ; |XDest
0040155B  |.  53            push    ebx                              ; |hDestDC
0040155C  |.  FF15 28604000 call    dword ptr [<&GDI32.BitBlt>]      ; \BitBlt
00401562  |.  85C0          test    eax, eax
00401564  |.  5B            pop     ebx
00401565  |.  75 7C         jnz     short 004015E3
00401567  |.  FF15 D8604000 call    dword ptr [<&KERNEL32.GetLastErr>; [GetLastError
0040156D  |.  6A 00         push    0                                ; /Arguments = NULL
0040156F  |.  8D5424 10     lea     edx, dword ptr [esp+10]          ; |
00401573  |.  6A 00         push    0                                ; |BufSize = 0
00401575  |.  52            push    edx                              ; |Buffer
00401576  |.  6A 00         push    0                                ; |LanguageId = 0 (LANG_NEUTRAL)
00401578  |.  50            push    eax                              ; |MessageId
00401579  |.  6A 00         push    0                                ; |pSource = NULL
0040157B  |.  68 00110000   push    1100                             ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|0
00401580  |.  FF15 DC604000 call    dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA
00401586  |.  8B4424 0C     mov     eax, dword ptr [esp+C]
0040158A  |.  8D4C24 68     lea     ecx, dword ptr [esp+68]
0040158E  |.  50            push    eax                              ; /<%s>
0040158F  |.  68 C8704000   push    004070C8                         ; |<%s> = "BitBlt(hdc, point.x+10, point.y+40, gDisplayRect.right-gDisplayRect.left, gDisplayRect.bottom-gDisplayRect.top, hDcMem, iHeight, 0, SRCCOPY)"
00401594  |.  68 BC704000   push    004070BC                         ; |<%s> = "BackPrnt.c"
00401599  |.  68 25010000   push    125                              ; |<%d> = 125 (293.)
0040159E  |.  68 78704000   push    00407078                         ; |Format = LF,"The following call failed at line %d in %s:",LF,LF,"    %s",LF,LF,"Reason: %s",LF,""
004015A3  |.  51            push    ecx                              ; |s
004015A4  |.  FF15 20614000 call    dword ptr [<&USER32.wsprintfA>]  ; \wsprintfA
004015AA  |.  83C4 18       add     esp, 18
004015AD  |.  8D9424 680100>lea     edx, dword ptr [esp+168]
004015B4  |.  68 04010000   push    104                              ; /BufSize = 104 (260.)
004015B9  |.  52            push    edx                              ; |PathBuffer
004015BA  |.  6A 00         push    0                                ; |hModule = NULL
004015BC  |.  FF15 E0604000 call    dword ptr [<&KERNEL32.GetModuleF>; \GetModuleFileNameA
004015C2  |.  8D8424 680100>lea     eax, dword ptr [esp+168]
004015C9  |.  68 30200100   push    12030                            ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL|10000
004015CE  |.  8D4C24 6C     lea     ecx, dword ptr [esp+6C]          ; |
004015D2  |.  50            push    eax                              ; |Title
004015D3  |.  51            push    ecx                              ; |Text
004015D4  |.  6A 00         push    0                                ; |hOwner = NULL
004015D6  |.  FF15 24614000 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
004015DC  |.  6A 01         push    1
004015DE  |.  E8 A0050000   call    00401B83
004015E3  |>  8B5424 0C     mov     edx, dword ptr [esp+C]
004015E7  |.  52            push    edx
004015E8  |.  56            push    esi
004015E9  |.  FFD5          call    ebp
004015EB  |.  56            push    esi                              ; /hDC
004015EC  |.  FF15 2C604000 call    dword ptr [<&GDI32.DeleteDC>]    ; \DeleteDC
004015F2  |.  8D4424 28     lea     eax, dword ptr [esp+28]
004015F6  |.  50            push    eax                              ; /pPaintstruct
004015F7  |.  57            push    edi                              ; |hWnd
004015F8  |.  FF15 28614000 call    dword ptr [<&USER32.EndPaint>]   ; \EndPaint
004015FE  |>  5F            pop     edi
004015FF  |.  5E            pop     esi
00401600  |.  5D            pop     ebp
00401601  |.  81C4 60020000 add     esp, 260
00401607  \.  C3            retn

 

 

print

 

 

你可能感兴趣的:(2-6)