C++ c++;winapi无法创建2个控件

C++ c++;winapi无法创建2个控件,c++,winapi,user-interface,listbox,richedit,C++,Winapi,User Interface,Listbox,Richedit,我正在尝试创建包含richedit控件和listbox控件的窗口, 问题是我创建的第二个控件没有显示。 我的意思是: 如果InitListClients函数将位于第一位,则只显示列表框, 如果InitEditLog将位于第一位,则只显示richedit 以下是功能: void ApostleServer::InitEditLog(HWND &_hwnd) { LoadLibrary(TEXT("Riched32.dll")); hEditLog = CreateWindo

我正在尝试创建包含richedit控件和listbox控件的窗口, 问题是我创建的第二个控件没有显示。 我的意思是:

如果
InitListClients
函数将位于第一位,则只显示列表框, 如果
InitEditLog
将位于第一位,则只显示richedit

以下是功能:

void ApostleServer::InitEditLog(HWND &_hwnd)
{
    LoadLibrary(TEXT("Riched32.dll"));
    hEditLog = CreateWindowEx(WS_EX_STATICEDGE, "richedit", "bla", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 310, _hwnd, NULL, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}

void ApostleServer::InitListClients(HWND &_hwnd)
{
    hListClients = CreateWindowEx(WS_EX_STATICEDGE, "listbox", "bla", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 550, 20, 150, 150, _hwnd, NULL, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
void ApostleServer::InitEditLog(HWND &_hwnd)
{
    LoadLibrary(TEXT("Riched32.dll"));
    CreateWindowExW(WS_EX_STATICEDGE, L"richedit", L"Text", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 306, _hwnd, (HMENU)IDC_EDITLOG, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}

void ApostleServer::InitListClients(HWND &_hwnd)
{
    CreateWindowExW(WS_EX_STATICEDGE, L"listbox", L"asd", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 410, 10, 160, 306, _hwnd, (HMENU)IDC_LISTCLIENTS, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
我是winapi的新手,我找不到解决这个问题的方法。 谢谢

编辑: 正如我所评论的,问题的原因是类成员的使用。 下面是我编写的一整段代码,它有着相同的问题:

#include <Windows.h>
#include <stdlib.h>

class Server
{
public:

    /* Fields */
    MSG* msg;
    WNDCLASSW* wc;
    HWND hListClients;
    HWND hEditLog;

    /* Methods */
    void InitEditLog(HWND &_hwnd)
    {
        LoadLibrary(TEXT("Riched32.dll"));
        hEditLog = CreateWindowExW(WS_EX_STATICEDGE, L"richedit", L"Text", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 306, _hwnd, (HMENU)2, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
    }

    void InitListClients(HWND &_hwnd)
    {
        // Here I'm using hListClients class member, and that what cause the problem (I will see only the list on the window)
        hListClients = CreateWindowExW(WS_EX_STATICEDGE, L"listbox", L"asd", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 410, 10, 160, 306, _hwnd, (HMENU)1, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
        // If I was only creating the listbox (without returning handler), I will see the listbox and the richedit.
    }

    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {

        Server* This = (Server*)GetWindowLongW(hwnd, GWL_USERDATA);

        switch(msg)
        {
            case WM_CREATE:
            {
                /* Initialize the clients list */
                This->InitListClients(hwnd); // Attention that I called this function first.

                /* Initialize the server log */
                This->InitEditLog(hwnd);
                // If I would call this function first, I will see only the richedit.

                return 0;
            }

            case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }
        }

        return DefWindowProcW(hwnd, msg, wParam, lParam);
    }

    Server(HINSTANCE &_hInstance)
    {
        msg = new MSG;
        wc = new WNDCLASSW;
        wc->style = CS_HREDRAW | CS_VREDRAW;
        wc->cbClsExtra = 0;
        wc->cbWndExtra = 0;
        wc->lpszClassName = L"ApostleServer";
        wc->hInstance = _hInstance;
        wc->hbrBackground = GetSysColorBrush(COLOR_3DFACE);
        wc->lpszMenuName = NULL;
        wc->lpfnWndProc = WndProc;
        wc->hCursor = LoadCursor(NULL, IDC_ARROW);
        wc->hIcon = LoadIcon(NULL, IDI_APPLICATION);

        RegisterClassW(&(*wc));
        CreateWindowW(wc->lpszClassName, L"Apostle Server", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 600, 400, 0, 0, _hInstance, 0);

        while(GetMessage(&(*msg), NULL, 0, 0))
        {
            TranslateMessage(&(*msg));
            DispatchMessage(&(*msg));
        }

    }
};

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    Server* srvr = new Server(hInstance);
    return 0;
}
#包括
#包括
类服务器
{
公众:
/*田地*/
味精*味精;
WNDCLASSW*wc;
HWND-hlist客户;
HWND hEditLog;
/*方法*/
void InitEditLog(HWND和uhwnd)
{
加载库(文本(“Riched32.dll”);
hEditLog=CreateWindowExW(WS_EX_STATICEDGE,L“richedit”,L“Text”,WS_CHILD,WS_VISIBLE,ES|u多行,10,10,390,306,_hwnd,(menu)2,(HINSTANCE)GetWindowLong(_hwnd,GWL_HINSTANCE),NULL);
}
void InitListClients(HWND和uhwnd)
{
//这里我使用的是hListClients类成员,这就是问题的原因(我将只看到窗口上的列表)
hListClients=CreateWindowExW(WS_EX_STATICEDGE,L“listbox”,L“asd”,WS_CHILD,WS_VISIBLE,LBS|NOTIFY,410,10160306,_hwnd,(menu)1,(HINSTANCE)GetWindowLong(_hwnd,GWL_HINSTANCE),NULL);
//如果我只是创建listbox(没有返回处理程序),我将看到listbox和richedit。
}
静态LRESULT回调WndProc(HWND HWND、UINT msg、WPARAM WPARAM、LPARAM LPARAM)
{
服务器*This=(服务器*)GetWindowLongW(hwnd,GWL_USERDATA);
开关(msg)
{
案例WM_创建:
{
/*初始化客户端列表*/
This->InitListClients(hwnd);//注意,我首先调用了这个函数。
/*初始化服务器日志*/
此->初始化日志(hwnd);
//如果我先调用这个函数,我将只看到richedit。
返回0;
}
案例WM_销毁:
{
PostQuitMessage(0);
返回0;
}
}
返回DefWindowProcW(hwnd、msg、wParam、lParam);
}
服务器(HINSTANCE和\u HINSTANCE)
{
味精=新味精;
wc=新WNDCLASSW;
wc->style=CS_HREDRAW | CS_VREDRAW;
wc->cbClsExtra=0;
wc->cbWndExtra=0;
wc->lpszClassName=L“ApostleServer”;
wc->hInstance=\u hInstance;
wc->hbrBackground=GetSysColorBrush(彩色);
wc->lpszMenuName=NULL;
wc->lpfnWndProc=WndProc;
wc->hCursor=LoadCursor(空,IDC_箭头);
wc->hIcon=LoadIcon(空,IDI_应用程序);
注册分类(&(*wc));
CreateWindowW(wc->lpszClassName,L“使徒服务器”,WS_重叠窗口| WS|u可见,100100600400,0,0,_hInstance,0);
while(GetMessage(&(*msg),NULL,0,0))
{
翻译信息(&(*msg));
调度消息(&(*msg));
}
}
};
int WINAPI wWinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、PWSTR pCmdLine、int nCmdShow)
{
服务器*srvr=新服务器(hInstance);
返回0;
}

通过在
WM\u CREATE
消息上创建控件(但不设置控件处理程序!)解决问题,并在创建主窗口后设置控件处理程序

WM\u创建
消息:

    case WM_CREATE:
    {
        /* Center the main window */
        This->CenterWindow(hwnd);

        /* Initialize the clients list */
        This->InitListClients(hwnd);

        /* Initialize the server log */
        This->InitEditLog(hwnd);


        return 0;
    }
创建主窗口后:

RegisterClassW(&(*wc));
hMainWindow = CreateWindowW(wc->lpszClassName, L"Apostle Server", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 600, 400, 0, 0, _hInstance, 0);

/* Set controls handlers */
hListClients = GetDlgItem(hMainWindow, IDC_LISTCLIENTS);
hEditLog = GetDlgItem(hMainWindow, IDC_EDITLOG);
InitEditLog
InitListClients
功能:

void ApostleServer::InitEditLog(HWND &_hwnd)
{
    LoadLibrary(TEXT("Riched32.dll"));
    hEditLog = CreateWindowEx(WS_EX_STATICEDGE, "richedit", "bla", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 310, _hwnd, NULL, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}

void ApostleServer::InitListClients(HWND &_hwnd)
{
    hListClients = CreateWindowEx(WS_EX_STATICEDGE, "listbox", "bla", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 550, 20, 150, 150, _hwnd, NULL, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}
void ApostleServer::InitEditLog(HWND &_hwnd)
{
    LoadLibrary(TEXT("Riched32.dll"));
    CreateWindowExW(WS_EX_STATICEDGE, L"richedit", L"Text", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 10, 10, 390, 306, _hwnd, (HMENU)IDC_EDITLOG, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}

void ApostleServer::InitListClients(HWND &_hwnd)
{
    CreateWindowExW(WS_EX_STATICEDGE, L"listbox", L"asd", WS_CHILD | WS_VISIBLE | LBS_NOTIFY, 410, 10, 160, 306, _hwnd, (HMENU)IDC_LISTCLIENTS, (HINSTANCE)GetWindowLong(_hwnd, GWL_HINSTANCE), NULL);
}

第一段代码相当奇怪。首先,C++中的< <代码> >代码>指针不是大写的。所以我假设这是一个指向窗口的C++对象的变量的名称。但是,为什么要将窗口句柄作为参数传递,而不是作为成员变量访问它呢?无论如何,不是什么破坏了你的代码,只是一些让人困惑的问题。另一个问题是,你使用的是8字节的ANSI字符串,尽管是2013年。现在所有Windows应用程序都应该是Unicode。请确保定义了
UNICODE
符号,并且字符串文本的前缀为
L
。不过,代码对我来说运行良好。所以问题不在于你给我们看的东西。您可以通过创建一个新项目并将代码片段一次添加回一个项目来自行调试。将字符串更改为unicode解决了我的问题,但有一个问题,是否有一个
CreateWindow
函数接收unicode字符串并具有扩展样式?CreateWindowEx就是它的名称。