本来我以为UNICODE版的程序,不可以在98下运行的。
但是今天我却遇到一件很郁闷,不知道怎么回事的事,具体如下:
我本来是用VC加2000系统作为开发环境的,今天早上的时候,
我换了一下,用的是BCB和98作为开发环境..我就把以前写的UNICODE版的
程序(是在VC和2000的环境下写的. )拿到BCB和98下编译运行..纯WIN32 SDK程序.
没有想到居然运行通过.我以前一直以为 98不可能运行UNICODE版的程序.
所以我就又重新用VC在98环境下编译这些文件..编译是通过了..
但是就是运行不能运行(但不是错误,只是说需要NT环境)
..所以我觉得有一点(基于WIN32SDK) 在VC和BCB上是不同的.
那就是BCB可以在WINDOWS 系列的操作系统上,编译UNICODE或非UNICODE版的程序.
并且编译后能运行..但是VC在98下只能编译非UNICODE版程序..而在NT下能编译两者.
但是编译好的UNICODE版的程序,不能在98下运行只能在NT 环境中正常运行.
就上面的这出现的这个问题,我想问的就是为什么会有这种情况.
在BCB的工程选项里的Directory/Condition里有一个预定义的宏的地方,默认是DEBUG,你加上UNICODE,之后编译出来的才是UNICODE程序,不然w_char,BSTR只能被解释为char
1.请确定你在98下用BCB编译的是UNICODE程序,并可运行。
2.根据windows核心编程上的说法,Win98只实现了几个UNICODE版API,其中MessageBoxW是一个。
这个问题,估计就是因为用到了只有Windows NT/2000/XP平台下才有的函数。而在BCB下,
虽然是SDK的代码,但是如果包含了头文件<vcl.h>的话,那么BCB的头文件,对一些只有在
Windows NT/2000/XP下的函数,重新进行了包装,
所以用BCB编译的程序可能没事。我没有你说的源程序,所以你只有贴出代码才知道是哪个
函数造成的。
我试了一下没问题:
我用的第三章的例子,为简化我把playsound去掉。
代码如下:
/*------------------------------------------------------------
HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
//PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
实践:
我在win2000 Professional下:
对VC6.0的非UNICODE版我按如下编译:
cl hellowin.c user32.lib gdi32.lib
得到24k的非UNICODE版hellowin.exe.在win2000和win98都可运行。
对VC6.0的UNICODE版我按如下编译:
cl -DUNICODE hellowin.c user32.lib gdi32.lib
得到24k的UNICODE版hellowin.exe.在win2000可运行,在win98下弹出对话框"This program requires Windows NT!"。
对c++ builder5.0的非UNICODE版我按如下编译:
bcc32 -tW hellowin.c
得到46.5k的非UNICODE版hellowin.exe.在win2000和win98都可运行。
对c++ builder5.0的UNICODE版我按如下编译:
bcc32 -tW -DUNICODE hellowin.c
得到46.5k的UNICODE版hellowin.exe.在win2000可运行,在win98下弹出对话框"This program requires Windows NT!"。
我在win98 下没装c++builder 我用的是Borland的freecommandLinetools。编译器是一样的。
bcc32 -tW hellowin.c
得到46.5k的非UNICODE版hellowin.exe.在win2000和win98都可运行。
bcc32 -tW -DUNICODE hellowin.c
得到46.5k的UNICODE版hellowin.exe.在win2000可运行,在win98下弹出对话框"This program requires Windows NT!"。
结论:
楼主在win98下用c++builder编译UNICODE版时方法有问题:编译的结果不是真正的UNICODE版可执行文件。
如何知道自己编译后的可执行文件是UNICODE版还是非UNICODE版呢?。我是用以下方法判断的:
对UNICODE版,我们调用的真正API函数名后面常以W结尾。如 在调用RegisterClass是真正调用的是RegisterClassW。
对非UNICODE版,我们调用的真正API函数名后面常以A结尾。如 在调用RegisterClass是真正调用的是RegisterClassA。
用c++ builder自带的Tdump.exe可对PE文件进行分析:
我对UNICODE版的hellowin.exe分解都到下列信息:
----------------
Imports from USER32.DLL
BeginPaint
CreateWindowExW
DefWindowProcW
DispatchMessageW
EndPaint
EnumThreadWindows
GetMessageW
LoadCursorW
LoadIconW
MessageBoxA
MessageBoxW
PostQuitMessage
RegisterClassW
ShowWindow
TranslateMessage
UpdateWindow
wsprintfA
------------------------
我对非UNICODE版的hellowin.exe分解都到下列信息:
------------------------
Imports from USER32.DLL
BeginPaint
CreateWindowExA
DefWindowProcA
DispatchMessageA
EndPaint
EnumThreadWindows
GetMessageA
LoadCursorA
LoadIconA
MessageBoxA
PostQuitMessage
RegisterClassA
ShowWindow
TranslateMessage
UpdateWindow
wsprintfA
------------------------
以上的分解可明显的看出编译后可执行文件是UNICODE版还是非UNICODE版。
以上是我个人的一些分析和理解。