3

当我运行这个 C 代码时:

// Get rid of the CRT and stuff; we don't need it
#pragma comment(linker, "/Entry:mainCRTStartup")
#pragma comment(linker, "/NoDefaultLib:msvcrt.lib")
#pragma comment(linker, "/NoDefaultLib:kernel32.lib")
#pragma comment(linker, "/NoDefaultLib:ntdll.lib")
#pragma comment(linker, "/Subsystem:Console")

#pragma comment(lib, "user32.lib")

#include <windows.h>

int mainCRTStartup()
{
    MSG msg;
    HWND hWndParent;
    WNDCLASS wndClass =
    {
        0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
        GetSysColorBrush(COLOR_3DFACE), NULL, TEXT("MyClass")
    };
    RegisterClass(&wndClass);
    hWndParent = CreateWindow(
        wndClass.lpszClassName, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        0, 0, 33, 100, NULL, NULL, NULL, NULL);
    CreateWindow(TEXT("Button"), wndClass.lpszClassName,
        WS_VISIBLE | WS_CHILD | BS_GROUPBOX,
        5, 5, 100, 50, hWndParent, NULL, NULL, NULL);
    while (GetMessage(&msg, hWndParent, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

我得到:

但是当我运行等效的D 代码时:

// Again, get rid of the runtime
pragma(startaddress, mainCRTStartup);
pragma(lib, "dmd_win32.lib");

import win32.windows;

int mainCRTStartup()
{
    MSG msg;
    HWND hWndParent;
    WNDCLASS wndClass =
    {
        0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
        GetSysColorBrush(COLOR_3DFACE), NULL, "MyClass"
    };
    RegisterClass(&wndClass);
    hWndParent = CreateWindow(
        wndClass.lpszClassName, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        0, 0, 33, 100, NULL, NULL, NULL, NULL);
    CreateWindow("Button", wndClass.lpszClassName,
        WS_VISIBLE | WS_CHILD | BS_GROUPBOX,
        5, 5, 100, 50, hWndParent, NULL, NULL, NULL);
    while (GetMessage(&msg, hWndParent, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

我得到:

我很困惑......什么可能导致这个白色背景?!

编辑:

我不确定它实际上是一个库错误......我刚刚删除了依赖项(并且我没有看到代码有任何问题),但问题仍然存在:

version = Unicode;
extern(Windows):
alias void* HWND, HMENU, HINSTANCE, HCURSOR, HBRUSH, HICON;
alias ushort ATOM, WORD;
alias uint UINT, DWORD;
alias int[2] POINT;
alias int BOOL;
alias int LONG;
alias size_t WPARAM, LPARAM, LRESULT;
alias char* LPSTR;
alias const(char)* LPCSTR;
alias wchar* LPWSTR;
alias const(wchar)* LPCWSTR;
version(Unicode)
{
    alias LPCWSTR LPCTSTR;
    alias LPWSTR LPTSTR;
    alias GetMessageW GetMessage;
    alias CreateWindowExW CreateWindowEx;
    alias DispatchMessageW DispatchMessage;
    alias DefWindowProcW DefWindowProc;
    alias LoadCursorW LoadCursor;
    alias RegisterClassW RegisterClass;
    alias WNDCLASSW WNDCLASS;
}
else
{
    alias LPCSTR LPCTSTR;
    alias LPSTR LPTSTR;
    alias GetMessageA GetMessage;
    alias CreateWindowExA CreateWindowEx;
    alias DispatchMessageA DispatchMessage;
    alias DefWindowProcA DefWindowProc;
    alias LoadCursorA LoadCursor;
    alias RegisterClassA RegisterClass;
    alias WNDCLASSA WNDCLASS;
}
LPCTSTR MAKEINTATOM(ATOM atom) { return cast(LPCTSTR)atom; }
ATOM RegisterClassA(WNDCLASSA*);
ATOM RegisterClassW(WNDCLASSW*);
HCURSOR LoadCursorA(HINSTANCE, LPCSTR);
HCURSOR LoadCursorW(HINSTANCE, LPCWSTR);
LRESULT DefWindowProcA(HWND, UINT, WPARAM, LPARAM);
LRESULT DefWindowProcW(HWND, UINT, WPARAM, LPARAM);
BOOL GetMessageA(const(MSG)*, HWND, UINT, UINT);
BOOL GetMessageW(const(MSG)*, HWND, UINT, UINT);
LONG DispatchMessageA(const(MSG)*);
LONG DispatchMessageW(const(MSG)*);
BOOL TranslateMessage(const(MSG)*);
HWND CreateWindowExA(int, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, void*);
HWND CreateWindowExW(int, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, void*);
HBRUSH GetSysColorBrush(int);
alias LRESULT function(HWND, UINT, WPARAM, LPARAM) WNDPROC;
enum
{
    NULL = null,
    COLOR_3DFACE = 15,
    BS_GROUPBOX = 7,
}
const LPCTSTR IDC_ARROW = cast(LPCTSTR)32512;
struct MSG
{
    HWND hwnd;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD  time;
    POINT  pt;
}
struct WNDCLASSA
{
    UINT      style;
    WNDPROC   lpfnWndProc;
    int       cbClsExtra;
    int       cbWndExtra;
    HINSTANCE hInstance;
    HICON     hIcon;
    HCURSOR   hCursor;
    HBRUSH    hbrBackground;
    LPCSTR   lpszMenuName;
    LPCSTR   lpszClassName;
}
struct WNDCLASSW
{
    UINT      style;
    WNDPROC   lpfnWndProc;
    int       cbClsExtra;
    int       cbWndExtra;
    HINSTANCE hInstance;
    HICON     hIcon;
    HCURSOR   hCursor;
    HBRUSH    hbrBackground;
    LPCWSTR   lpszMenuName;
    LPCWSTR   lpszClassName;
}
enum
{
    WS_OVERLAPPED       = 0,
    WS_TILED            = WS_OVERLAPPED,
    WS_MAXIMIZEBOX      = 0x00010000,
    WS_MINIMIZEBOX      = 0x00020000,
    WS_TABSTOP          = 0x00010000,
    WS_GROUP            = 0x00020000,
    WS_THICKFRAME       = 0x00040000,
    WS_SIZEBOX          = WS_THICKFRAME,
    WS_SYSMENU          = 0x00080000,
    WS_HSCROLL          = 0x00100000,
    WS_VSCROLL          = 0x00200000,
    WS_DLGFRAME         = 0x00400000,
    WS_BORDER           = 0x00800000,
    WS_CAPTION          = 0x00c00000,
    WS_OVERLAPPEDWINDOW = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,
    WS_TILEDWINDOW      = WS_OVERLAPPEDWINDOW,
    WS_MAXIMIZE         = 0x01000000,
    WS_CLIPCHILDREN     = 0x02000000,
    WS_CLIPSIBLINGS     = 0x04000000,
    WS_DISABLED         = 0x08000000,
    WS_VISIBLE          = 0x10000000,
    WS_MINIMIZE         = 0x20000000,
    WS_ICONIC           = WS_MINIMIZE,
    WS_CHILD            = 0x40000000,
    WS_CHILDWINDOW      = 0x40000000,
    WS_POPUP            = 0x80000000,
    WS_POPUPWINDOW      = WS_POPUP|WS_BORDER|WS_SYSMENU,
}

pragma(startaddress, mainCRTStartup);

int mainCRTStartup()
{
    MSG msg;
    HWND hWndParent;
    WNDCLASS wndClass =
    {
        0, &DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),
        GetSysColorBrush(COLOR_3DFACE), NULL, "MyClass"
    };
    ATOM atom = RegisterClass(&wndClass);
    hWndParent = CreateWindowEx(
        0, wndClass.lpszClassName, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        0, 0, 33, 100, NULL, NULL, NULL, NULL);
    CreateWindowEx(0, "Button", wndClass.lpszClassName,
        WS_VISIBLE | WS_CHILD | BS_GROUPBOX,
        5, 5, 100, 50, hWndParent, NULL, NULL, NULL);
    while (GetMessage(&msg, hWndParent, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

要么我做错了,要么是编译器错误……但即使是编译器错误,我仍然不知道这样的事情是如何发生的,因为它需要调用非常特定的 API!想法?

4

2 回答 2

9

这是子系统版本问题(链接器责任)。添加-L/SUBSYSTEM:CONSOLE:4.0dmd命令行以修复MyClass背景颜色。Walter 喜欢旧系统,因此默认的 OPTLINK子系统版本是 3.10。看起来微软的 link9.0 使用 5.0 作为默认子系统版本。

于 2012-06-04T17:52:20.557 回答
3

Linux的家伙在这里,所以我会尽力而为:

它看起来像图书馆本身的问题。我猜你是从这里得到的吗?

https://github.com/AndrejMitrovic/DWinProgramming

在这种情况下,解决方案是联系编写您正在使用的 dmd win32 库的人。如果您从源代码编译它们,那么肯定有办法联系该人。看来您发现了一个错误!

PS:如果您从源代码编译库,还有另一种可能性。您可能有一个不同的编译参数或标志,并导致差异。此外,这可能是与库依赖项的兼容性问题。在这种情况下,答案仍然是联系库的开发人员。他可能会要求您提供一些编译输出。

于 2012-06-04T11:33:28.600 回答