2-6

it2022-05-09  26

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, 260004014AB  |.  85C0          test    eax, eax004014AD  |.  55            push    ebp004014AE  |.  56            push    esi004014AF  |.  57            push    edi004014B0  |.  0F84 48010000 je      004015FE004014B6  |.  8BBC24 700200>mov     edi, dword ptr [esp+270]004014BD  |.  53            push    ebx004014BE  |.  68 E9030000   push    3E9                              ; /ControlID = 3E9 (1001.)004014C3  |.  57            push    edi                              ; |hWnd004014C4  |.  FF15 14614000 call    dword ptr [<&USER32.GetDlgItem>] ; \GetDlgItem004014CA  |.  8BF0          mov     esi, eax004014CC  |.  8D4424 2C     lea     eax, dword ptr [esp+2C]004014D0  |.  50            push    eax                              ; /pPaintstruct004014D1  |.  57            push    edi                              ; |hWnd004014D2  |.  FF15 18614000 call    dword ptr [<&USER32.BeginPaint>] ; \BeginPaint004014D8  |.  8D4C24 1C     lea     ecx, dword ptr [esp+1C]004014DC  |.  8BD8          mov     ebx, eax004014DE  |.  51            push    ecx                              ; /pRect004014DF  |.  56            push    esi                              ; |hWnd004014E0  |.  FF15 34614000 call    dword ptr [<&USER32.GetWindowRec>; \GetWindowRect004014E6  |.  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], edx004014F6  |.  51            push    ecx                              ; /pPoint004014F7  |.  57            push    edi                              ; |hWnd004014F8  |.  894424 20     mov     dword ptr [esp+20], eax          ; |004014FC  |.  FF15 1C614000 call    dword ptr [<&USER32.ScreenToClie>; \ScreenToClient00401502  |.  6A 00         push    0                                ; /hDC = NULL00401504  |.  FF15 24604000 call    dword ptr [<&GDI32.CreateCompati>; \CreateCompatibleDC0040150A  |.  8B15 20994000 mov     edx, dword ptr [409920]00401510  |.  8B2D 00604000 mov     ebp, dword ptr [<&GDI32.SelectOb>;  GDI32.SelectObject00401516  |.  8BF0          mov     esi, eax00401518  |.  52            push    edx                              ; /hObject => 7F05063100401519  |.  56            push    esi                              ; |hDC0040151A  |.  FFD5          call    ebp                              ; \SelectObject0040151C  |.  8B0D 1C984000 mov     ecx, dword ptr [40981C]00401522  |.  894424 10     mov     dword ptr [esp+10], eax00401526  |.  A1 2C994000   mov     eax, dword ptr [40992C]0040152B  |.  68 2000CC00   push    0CC0020                          ; /ROP = SRCCOPY00401530  |.  8B15 18984000 mov     edx, dword ptr [409818]          ; |00401536  |.  6A 00         push    0                                ; |YSrc = 000401538  |.  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                              ; |hSrcDC00401545  |.  51            push    ecx                              ; |Height00401546  |.  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                              ; |Width00401556  |.  83C1 0A       add     ecx, 0A                          ; |00401559  |.  50            push    eax                              ; |YDest0040155A  |.  51            push    ecx                              ; |XDest0040155B  |.  53            push    ebx                              ; |hDestDC0040155C  |.  FF15 28604000 call    dword ptr [<&GDI32.BitBlt>]      ; \BitBlt00401562  |.  85C0          test    eax, eax00401564  |.  5B            pop     ebx00401565  |.  75 7C         jnz     short 004015E300401567  |.  FF15 D8604000 call    dword ptr [<&KERNEL32.GetLastErr>; [GetLastError0040156D  |.  6A 00         push    0                                ; /Arguments = NULL0040156F  |.  8D5424 10     lea     edx, dword ptr [esp+10]          ; |00401573  |.  6A 00         push    0                                ; |BufSize = 000401575  |.  52            push    edx                              ; |Buffer00401576  |.  6A 00         push    0                                ; |LanguageId = 0 (LANG_NEUTRAL)00401578  |.  50            push    eax                              ; |MessageId00401579  |.  6A 00         push    0                                ; |pSource = NULL0040157B  |.  68 00110000   push    1100                             ; |Flags = ALLOCATE_BUFFER|FROM_SYSTEM|000401580  |.  FF15 DC604000 call    dword ptr [<&KERNEL32.FormatMess>; \FormatMessageA00401586  |.  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                              ; |s004015A4  |.  FF15 20614000 call    dword ptr [<&USER32.wsprintfA>]  ; \wsprintfA004015AA  |.  83C4 18       add     esp, 18004015AD  |.  8D9424 680100>lea     edx, dword ptr [esp+168]004015B4  |.  68 04010000   push    104                              ; /BufSize = 104 (260.)004015B9  |.  52            push    edx                              ; |PathBuffer004015BA  |.  6A 00         push    0                                ; |hModule = NULL004015BC  |.  FF15 E0604000 call    dword ptr [<&KERNEL32.GetModuleF>; \GetModuleFileNameA004015C2  |.  8D8424 680100>lea     eax, dword ptr [esp+168]004015C9  |.  68 30200100   push    12030                            ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL|10000004015CE  |.  8D4C24 6C     lea     ecx, dword ptr [esp+6C]          ; |004015D2  |.  50            push    eax                              ; |Title004015D3  |.  51            push    ecx                              ; |Text004015D4  |.  6A 00         push    0                                ; |hOwner = NULL004015D6  |.  FF15 24614000 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA004015DC  |.  6A 01         push    1004015DE  |.  E8 A0050000   call    00401B83004015E3  |>  8B5424 0C     mov     edx, dword ptr [esp+C]004015E7  |.  52            push    edx004015E8  |.  56            push    esi004015E9  |.  FFD5          call    ebp004015EB  |.  56            push    esi                              ; /hDC004015EC  |.  FF15 2C604000 call    dword ptr [<&GDI32.DeleteDC>]    ; \DeleteDC004015F2  |.  8D4424 28     lea     eax, dword ptr [esp+28]004015F6  |.  50            push    eax                              ; /pPaintstruct004015F7  |.  57            push    edi                              ; |hWnd004015F8  |.  FF15 28614000 call    dword ptr [<&USER32.EndPaint>]   ; \EndPaint004015FE  |>  5F            pop     edi004015FF  |.  5E            pop     esi00401600  |.  5D            pop     ebp00401601  |.  81C4 60020000 add     esp, 26000401607  \.  C3            retn

 

 

print

 

 

转载于:https://www.cnblogs.com/nanshouyong326/archive/2010/07/08/1773432.html


最新回复(0)