HITEA 版 (精华区)

发信人: hfl (凤凰·风中轻舞), 信区: HITEA
标  题: Win32汇编语言(六)
发信站: 哈工大紫丁香 (2002年04月02日21:21:07 星期二), 站内信件

六、资源在Win32汇编语言程序中的使用

资源在Win32应用程序中是很重要的,笔者编写了一个使用资源的C语言程序,该程
序实现了菜单和一个“About”对话框,程序如下:
源程序(GENERIC.C):

#include <windows.h>
#include "resource.h"

static HINSTANCE hInst;
static char szWindowClass[]="GENERIC";

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam);
BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM
lParam);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nShowCmd)
{
 WNDCLASSEXA wcex;
 HWND hWnd;
 MSG msg;
 hInst=hInstance;
 if(!hPrevInstance)
 {
  wcex.cbSize=sizeof(WNDCLASSEXA);
  wcex.style=CS_HREDRAW|CS_VREDRAW;
  wcex.cbClsExtra=0;
  wcex.cbWndExtra=0;
  wcex.lpfnWndProc=WndProc;
  wcex.hInstance=hInstance;
  wcex.hIcon=LoadIconA(hInstance,IDI_APPLICATION);
  wcex.hCursor=LoadCursorA(0,IDC_ARROW);
  wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName=MAKEINTRESOURCE(IDR_MAINMENU);
  wcex.lpszClassName=szWindowClass;
  wcex.hIconSm=LoadIconA(hInstance,IDI_APPLICATION);
  if(!RegisterClassExA(&wcex)) return FALSE;
 }
 hWnd=CreateWindowExA(0,szWindowClass,"Generic",
WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
       0,0,hInstance,NULL);
 if(!hWnd) return FALSE;
 ShowWindow(hWnd,nShowCmd);
 UpdateWindow(hWnd);
 while(GetMessageA(&msg,0,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessageA(&msg);
 }
 return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM
lParam)
{
 HDC hDC;
 PAINTSTRUCT ps;
 switch(message)
 {
 case WM_COMMAND:
  switch(LOWORD(wParam))
  {
  case IDM_EXIT:
   SendMessageA(hWnd,WM_CLOSE,0,0);
   return 0;
  case IDM_ABOUT:
   DialogBoxParamA(hInst,MAKEINTRESOURCE(IDD_ABOUT),
hWnd,(DLGPROC)AboutDlgProc,0);
   return 0;
  default:
   return DefWindowProcA(hWnd,message,wParam,lParam)
;
  }
 case WM_PAINT:
  hDC=BeginPaint(hWnd,&ps);
  EndPaint(hWnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 default:
  return DefWindowProcA(hWnd,message,wParam,lParam);
 }
 return -1;
}

BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM
lParam)
{
 switch(message)
 {
 case WM_INITDIALOG:
  return TRUE;
 case WM_COMMAND:
  if((LOWORD(wParam)==IDOK)||(LOWORD(wParam)==IDCANCEL))
  {
   EndDialog(hDlg,LOWORD(wParam));
   return TRUE;
  }
  return FALSE;
 default:
  return FALSE;
 }
}

资源源文件(GENERIC.RC,使用Visual C++ 6.0建立):

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
////////////////////////////////////////////////////////////////////////
/////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

////////////////////////////////////////////////////////////////////////
/////
#undef APSTUDIO_READONLY_SYMBOLS

////////////////////////////////////////////////////////////////////////
/////
// Chinese (P.R.C.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

////////////////////////////////////////////////////////////////////////
/////
//
// Menu
//

IDR_MAINMENU MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&Exit",                       IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About...",                   IDM_ABOUT
    END
END


#ifdef APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////
/////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


////////////////////////////////////////////////////////////////////////
/////
//
// Dialog
//

IDD_ABOUT DIALOG DISCARDABLE  0, 0, 92, 65
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 9, "宋体"
BEGIN
    LTEXT           "Generic V1.0",IDC_STATIC1,20,10,50,10
    DEFPUSHBUTTON   "OK",IDOK,20,40,50,15
END


////////////////////////////////////////////////////////////////////////
/////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
    IDD_ABOUT, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 85
        TOPMARGIN, 7
        BOTTOMMARGIN, 58
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // Chinese (P.R.C.) resources
////////////////////////////////////////////////////////////////////////
/////



#ifndef APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////
/////
//
// Generated from the TEXTINCLUDE 3 resource.
//


////////////////////////////////////////////////////////////////////////
/////
#endif    // not APSTUDIO_INVOKED


资源头文件(RESOURCE.H,Visual C++ 6.0自动建立):

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by GENERIC.rc
//
#define IDR_MAINMENU                    101
#define IDD_ABOUT                       102
#define IDC_STATIC1                     1000
#define IDM_EXIT                        40001
#define IDM_ABOUT                       40002

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        103
#define _APS_NEXT_COMMAND_VALUE         40003
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

本程序与一般Win32编程资料中的GENERIC程序基本相同,只是只使用ANSI字符集。
现在笔者用Win32汇编语言程序实现本程序的功能,程序如下:
包含文件(GENERIC.INC):

UINT  TYPEDEF  DWORD
LONG  TYPEDEF  DWORD
LPSTR  TYPEDEF  PTR BYTE
LPCSTR  TYPEDEF  LPSTR
PVOID  TYPEDEF  PTR
LPVOID  TYPEDEF  PVOID
HANDLE  TYPEDEF  PVOID
HINSTANCE TYPEDEF  HANDLE
HWND  TYPEDEF  HANDLE
HMENU  TYPEDEF  HANDLE
HDC  TYPEDEF  HANDLE
HGDIOBJ  TYPEDEF  HANDLE
HICON  TYPEDEF  HANDLE
HCURSOR  TYPEDEF  HANDLE
HBRUSH  TYPEDEF  HANDLE

tagWNDCLASSEXA STRUCT
 cbSize  UINT  ?
 style  UINT  ?
 lpfnWndProc DWORD  ?
 cbClsExtra DWORD  ?
 cbWndExtra DWORD  ?
 hInstance DWORD  ?
 hIcon  DWORD  ?
 hCursor  DWORD  ?
 hbrBackground DWORD  ?
 lpszMenuName DWORD  ?
 lpszClassName DWORD  ?
 hIconSm  DWORD  ?
tagWNDCLASSEXA ENDS

WNDCLASSEXA TYPEDEF  tagWNDCLASSEXA

tagPOINT STRUCT
 x  LONG  ?
 y  LONG  ?
tagPOINT ENDS

POINT  TYPEDEF  tagPOINT

tagMSG  STRUCT
 message  UINT  ?
 wParam  DWORD  ?
 lParam  DWORD  ?
 time  DWORD  ?
 pt  POINT  <>
tagMSG  ENDS

MSG  TYPEDEF  tagMSG
LPMSG  TYPEDEF  PTR MSG

tagRECT  STRUCT
 left  LONG  ?
 top  LONG  ?
 right  LONG  ?
 bottom  LONG  ?
tagRECT  ENDS

RECT  TYPEDEF  tagRECT

tagPAINTSTRUCT STRUCT
 hdc  DWORD  ?
 fErase  DWORD  ?
 rcPaint  RECT  <>
 fRestore DWORD  ?
 fIncUpdate DWORD  ?
 rgbReserved BYTE  32 DUP(?)
tagPAINTSTRUCT ENDS

PAINTSTRUCT TYPEDEF  tagPAINTSTRUCT
LPPAINTSTRUCT TYPEDEF  PTR PAINTSTRUCT

NULL   =  0

TRUE   =  0ffffffffh
FALSE   =  0

SW_SHOWDEFAULT  =  10

CS_HREDRAW  =  0002h
CS_VREDRAW  =  0001h

IDI_APPLICATION  =  32512
IDC_ARROW  =  32512

COLOR_WINDOW  =  5

WS_OVERLAPPEDWINDOW =  00cf0000h

CW_USEDEFAULT  =  80000000h

WM_COMMAND  =  0111h
WM_CLOSE  =  0010h
WM_PAINT  =  000fh
WM_DESTROY  =  0002h
WM_INITDIALOG  =  0110h

IDOK   =  1
IDCANCEL  =  2

GetModuleHandleA PROTO stdcall, :LPCSTR
GetCommandLineA  PROTO stdcall
ExitProcess  PROTO stdcall, :UINT
LoadIconA  PROTO stdcall, :HINSTANCE,:LPCSTR
LoadCursorA  PROTO stdcall, :HINSTANCE,:LPCSTR
RegisterClassExA PROTO stdcall, :PTR WNDCLASSEXA
CreateWindowExA  PROTO stdcall, :DWORD,:LPCSTR,:LPCSTR,:DWORD,:
DWORD,:DWORD,:DWORD,:DWORD,:HWND,:HMENU,:HINSTANCE,:LPVOID
ShowWindow  PROTO stdcall, :HWND,:DWORD
UpdateWindow  PROTO stdcall, :HWND
GetMessageA  PROTO stdcall, :LPMSG,:HWND,:UINT,:UINT
TranslateMessage PROTO stdcall, :PTR MSG
DispatchMessageA PROTO stdcall, :PTR MSG
SendMessageA  PROTO stdcall, :HWND,:UINT,:DWORD,:DWORD
DialogBoxParamA  PROTO stdcall, :HINSTANCE,:LPCSTR,:HWND,:DWORD,:
DWORD
BeginPaint  PROTO stdcall, :HWND,:LPPAINTSTRUCT
EndPaint  PROTO stdcall, :HWND,:PTR PAINTSTRUCT
PostQuitMessage  PROTO stdcall, :DWORD
DefWindowProcA  PROTO stdcall, :HWND,:UINT,:DWORD,:DWORD
EndDialog  PROTO stdcall, :HWND,:DWORD

资源包含文件(RESOURCE.INC):

IDR_MAINMENU  =  101
IDD_ABOUT  =  102
IDC_STATIC1  =  1000
IDM_EXIT  =  40001
IDM_ABOUT  =  40002

源程序(GENERIC.ASM):

.386p

.MODEL flat,stdcall

INCLUDE GENERIC.INC
INCLUDE RESOURCE.INC

WinMain   PROTO stdcall, :HINSTANCE,:HINSTANCE,:LPSTR,:
DWORD

.STACK 4096

.DATA
 WindowClass BYTE  'GENERIC',0
 WindowTitle BYTE  'Generic',0
 hInst1  HINSTANCE 0
 lpCmdLine1 LPSTR  0

.CODE

_start:
 INVOKE GetModuleHandleA,NULL
 mov hInst1,eax
 INVOKE GetCommandLineA
 mov lpCmdLine1,eax
 INVOKE WinMain,hInst1,NULL,lpCmdLine1,SW_SHOWDEFAULT
 INVOKE ExitProcess,eax

WinMain PROC hInst:HINSTANCE,hPrevInst:HINSTANCE,lpCmdLine:LPSTR,
nShowCmd:DWORD
 LOCAL wcex:WNDCLASSEXA
 LOCAL hWnd:HWND
 LOCAL msg:MSG
 .IF !hPrevInst
  mov wcex.cbSize,SIZEOF WNDCLASSEXA
  mov wcex.style,CS_HREDRAW or CS_VREDRAW
  mov wcex.cbClsExtra,0
  mov wcex.cbWndExtra,0
  mov wcex.lpfnWndProc,OFFSET WndProc
  mov eax,hInst
  mov wcex.hInstance,eax
  INVOKE LoadIconA,hInst,IDI_APPLICATION
  mov wcex.hIcon,eax
  INVOKE LoadCursorA,0,IDC_ARROW
  mov wcex.hCursor,eax
  mov wcex.hbrBackground,COLOR_WINDOW+1
  mov wcex.lpszMenuName,IDR_MAINMENU and 0000ffffh
  mov wcex.lpszClassName,OFFSET WindowClass
  INVOKE LoadIconA,hInst,IDI_APPLICATION
  mov wcex.hIconSm,eax
  INVOKE RegisterClassExA,ADDR wcex
  .IF !eax
   mov eax,FALSE
   ret
  .ENDIF
 .ENDIF
 INVOKE CreateWindowExA,0,ADDR WindowClass,ADDR WindowTitle,
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,0,0,hInst,NULL
 mov hWnd,eax
 .IF !eax
  mov eax,FALSE
  ret
 .ENDIF
 INVOKE ShowWindow,hWnd,nShowCmd
 INVOKE UpdateWindow,hWnd
 .WHILE TRUE
  INVOKE GetMessageA,ADDR msg,0,0,0
  .BREAK .IF !eax
  INVOKE TranslateMessage,ADDR msg
  INVOKE DispatchMessageA,ADDR msg
 .ENDW
 mov eax,msg.wParam
 ret
WinMain ENDP

WndProc PROC hWnd:HWND,message:UINT,wParam:DWORD,lParam:DWORD
 LOCAL hDC:HDC
 LOCAL ps:PAINTSTRUCT
 .IF message==WM_COMMAND
  mov eax,wParam
  .IF ax==IDM_EXIT
   INVOKE SendMessageA,hWnd,WM_CLOSE,0,0
   mov eax,0
   ret
  .ELSEIF ax==IDM_ABOUT
   mov ebx,OFFSET AboutDlgProc
   INVOKE DialogBoxParamA,hInst1,IDD_ABOUT and
0000ffffh,hWnd,ebx,0
   mov eax,0
   ret
  .ELSE
   INVOKE DefWindowProcA,hWnd,message,wParam,
lParam
   ret
  .ENDIF
 .ELSEIF message==WM_PAINT
  INVOKE BeginPaint,hWnd,ADDR ps
  mov hDC,eax
  INVOKE EndPaint,hWnd,ADDR ps
  mov eax,0
  ret
 .ELSEIF message==WM_DESTROY
  INVOKE PostQuitMessage,0
  mov eax,0
  ret
 .ELSE
  INVOKE DefWindowProcA,hWnd,message,wParam,lParam
  ret
 .ENDIF
 mov eax,0ffffffffh
 ret
WndProc ENDP

AboutDlgProc PROC hDlg:HWND,message:UINT,wParam:DWORD,lParam:DWORD
 .IF message==WM_INITDIALOG
  mov eax,TRUE
  ret
 .ELSEIF message==WM_COMMAND
  mov eax,wParam
  .IF (ax==IDOK)||(ax==IDCANCEL)
   INVOKE EndDialog,hDlg,ax
   mov eax,TRUE
   ret
  .ENDIF
  mov eax,FALSE
  ret
 .ELSE
  mov eax,FALSE
  ret
 .ENDIF
 mov eax,FALSE
 ret
AboutDlgProc ENDP

PUBLIC _start

END

汇编连接本程序的命令如下:

ml /c /coff /Cp generic.asm
rc generic.rc
link /subsystem:windows /entry:_start generic.obj generic.res kernel32.
lib user32.lib gdi32.lib

运行汇编连接后生成的GENERIC.EXE文件,屏幕上将显示出一个带有菜单的窗口,
窗口的标题是“Generic”,菜单有两个主菜单项,分别是“File”和“Help”,
选择“File”菜单项下的“Exit”菜单项可以退出程序,选择“Help”菜单项下的
“About”菜单项可以显示“About”对话框。
本程序与SIMPLE.C程序很相似,Win32汇编语言程序中使用资源的方法也与C语言程
序没有很大的差别,都可以用资源编辑工具生成资源源文件和资源头文件,然后使
用资源编译器编译资源源文件,将生成的资源文件(RES文件)与汇编器生成的目
标文件和引入库文件连接在一起就可以了(资源头文件需要移植到汇编语言上,建
立一个资源包含文件)。
C语言程序中的MAKEINTRESOURCE宏的实质是将资源标识符数值的高位字(不用)清
零,然后强行转换成字符指针,Win32汇编语言程序中可以将资源标识符数值与
0000FFFFH作AND运算。




--
                       `'`;,
                         ___H_   _(`)
                       _/\    \ ( )  )        何时才能有一个属于自己的家!
                     /\__\\____\(  )_)
                     ||""||''''| |`|
                   ~~~`""""`""""`~~~~~~       

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.229.253]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.205毫秒