漢化分兩塊,一個和封包有關,另一個就是搞程序。這部分和一般的軟件漢化差不多,我這方面經驗實在是少,什麼時候把漢化新世紀的教材拿出來看看。
今天研究一個程序,找了半天沒有DialogBox,或者CreateDialog。最後調下來覺得在comctl32裏面,裏面就一個函數PropertySheetA。於是拿出api手冊,原來如此,還有這麼一個東西。
int PropertySheet(
LPCPROPSHEETHEADER lppsph
);
這玩意兒只有一個參數 LPCPROPSHEETHEADER lppsph,該結構如下:
typedef struct _PROPSHEETHEADER { // psh
DWORD dwSize;
DWORD dwFlags;
HWND hwndParent;
HINSTANCE hInstance;
union {
HICON hIcon;
LPCTSTR pszIcon;
};
LPCTSTR pszCaption;
UINT nPages
union {
UINT nStartPage
LPCTSTR pStartPage;
};
union {
LPCPROPSHEETPAGE ppsp;
HPROPSHEETPAGE FAR *phpage;
};
PFNPROPSHEETCALLBACK pfnCallback;
} PROPSHEETHEADER, FAR *LPPROPSHEETHEADER;
第二個字段Flag很重要,Remarks裏面提到“If the dwFlags member of the PROPSHEETHEADER structure specifies the PSH_MODELESS flag, PropertySheet creates a modeless dialog and returns immediately after the dialog is created. In this case, the PropertySheet return value is the window handle of the modeless dialog. ”,其他flag做啥我沒試過,反正這個flag能創建一個無模式的對話框。(其實調進去也能看到,還是用CreateDialogIndirectParam創建對話框的,但是一開始下he的話od不讓。)
倒數第二個字段pStartPage是一個指針,指向PROPSHEETPAGE結構的數組,該結構定義如下:
typedef struct _PROPSHEETPAGE { // psp
DWORD dwSize;
DWORD dwFlags;
HINSTANCE hInstance;
union {
LPCTSTR pszTemplate;
LPCDLGTEMPLATE pResource;
};
union {
HICON hIcon;
LPCTSTR pszIcon;
};
LPCTSTR pszTitle;
DLGPROC pfnDlgProc;
LPARAM lParam;
LPFNPSPCALLBACK pfnCallback;
UINT FAR * pcRefParent;
} PROPSHEETPAGE, FAR *LPPROPSHEETPAGE;
這個結構中pfnDlgProc最爲重要,裏面是一個消息循環,進入一個通用的dialogproc之後,斷在WM_INIT上,再進去,就是初始化Dialog的代碼,一般來說往list/combo等控件添加項的代碼都在這裏。
下面用例子來說明一下,先斷PropertySheetA
0044FE42 |. E8 6D7C1900 call <jmp.&COMCTL32.PropertySheetA> ; /PropertySheetA
看堆棧
0012FB9C 0012FBA8 /pPropSheetHeader = 0012FBA8
跟蹤過去
PROPSHEETHEADER部分
0012FA38 28 00 00 00 88 00 00 00 30 07 07 00 00 00 00 00
- size - - flag -
0012FA48 00 00 00 00 70 76 5F 00 04 00 00 00 00 00 00 00
- caption - - nPages -
0012FA58 60 FA 12 00 00 00 00 00
- ppsp -
PROPSHEETPAGE List 部分
28 00 00 00 00 00 00 00
list[0] - size -
0012FA68 00 00 40 00 23 76 5F 00 00 00 00 00 00 00 00 00
- template -
0012FA78 BC ED 44 00 00 00 00 00 00 00 00 00 00 00 00 00
- pfnDlgProc -
0012FA88 28 00 00 00 00 00 00 00 00 00 40 00 34 76 5F 00
// list[1]
0012FA98 00 00 00 00 00 00 00 00 B8 F2 44 00 00 00 00 00
0012FAA8 00 00 00 00 00 00 00 00 28 00 00 00 00 00 00 00
// list[2]
0012FAB8 00 00 40 00 46 76 5F 00 00 00 00 00 00 00 00 00
0012FAC8 74 F5 44 00 00 00 00 00 00 00 00 00 00 00 00 00
0012FAD8 28 00 00 00 00 00 00 00 00 00 40 00 5C 76 5F 00
// list[3]
0012FAE8 00 00 00 00 00 00 00 00 A0 F6 44 00 00 00 00 00
0012FAF8 00 00 00 00 00 00 00 00 00 00 40 00 30 07 07 00
對4個pfnDlgProc下斷,斷在第一個函數44EDBC。F7一路下去找到來到這裏:
0045063B |> /8B55 0C mov edx, dword ptr [ebp+C] ; Case 110 (WM_INITDIALOG) of switch 004505F9
0045063E |. 52 push edx
0045063F |. 50 push eax
00450640 |. 8B08 mov ecx, dword ptr [eax]
00450642 |. FF51 04 call dword ptr [ecx+4] ; 0045083C
斷在450642,然後F7進去就行了。