绘制Win32子窗口

时间:2014-10-24 19:52:36

标签: c++ winapi

大家好,我一直在尝试在WM_PAINT之外绘制到我的子窗口,而不是在子窗口上绘画,它在窗口上绘制到屏幕上我认为可能是因为x和y的位置但是应该& #39; t point(0,0)是子窗口的左上角而不是我实际屏幕的左上角? 这是我为了尝试绘制到子窗口而编写的代码:

#pragma warning(disable:4996)
#pragma comment(lib, "Ws2_32.lib")
#include <Windows.h>
#define WIDTH 800
#define HEIGHT 600
#define CLASS_NAME "Class"
#define IDC_MAIN_EDIT   101
#define IDC_WINDOW 102
int x = 0, y = 0;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void print_line(HWND hwnd, char *Msg);
void Println();
int Run();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

    WNDCLASSEX  wcex = { 0 };
    MSG         msg;
    HWND        hwnd = NULL;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_VREDRAW | CS_OWNDC;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = NULL;
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = CLASS_NAME;
    wcex.hInstance = hInstance;
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    if (!RegisterClassEx(&wcex))
    {
        MessageBoxA(NULL, "Failed to register class", "Error", MB_OK | MB_ICONERROR);
        return -1;
    }
    hwnd = CreateWindow(CLASS_NAME //Name of the window class
        , CLASS_NAME//Title of the window
        , WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN// the window style
        , 0 //x Postition of the window
        , 0// y position of the windpo
        , WIDTH, HEIGHT, // Width and Height
        NULL,//Parent window(we have no parent window)
        NULL,//Menu(we are not using menu's)
        hInstance,//application handle
        NULL);//Creates the window
    if (!hwnd)
    {
        MessageBoxA(NULL, "Failed to register class", "Error", MB_OK | MB_ICONERROR);
        return -2;
    }
    ShowWindow(hwnd, nCmdShow);
    return Run();
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HWND hEdit = NULL;
    HWND hWindow = NULL;
    #define Print(msg2) print_line(hWindow, msg2)

    switch (msg)
    {
    case WM_CREATE:

        hWindow = CreateWindowEx(WS_EX_CLIENTEDGE, "Window", "",
            WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL | WS_CLIPSIBLINGS,
            0, 0, WIDTH, HEIGHT - 25, hwnd, (HMENU)IDC_WINDOW, GetModuleHandle(NULL), NULL);

        hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
            WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL,
            0, 535, WIDTH, 25, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);


        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_COMMAND:
        Print("Hello");
        break;
    default:
        return (DefWindowProc(hwnd, msg, wParam, lParam));

    }
}
int Run()
{



    MSG msg = { 0 };

    WSAData wsa;
    WORD DllVersion = MAKEWORD(2, 1);
    if (WSAStartup(DllVersion, &wsa) != 0) return -1;

    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);


        }

    }
    return 0;
}
void print_line(HWND hwnd, char *Msg)
{

    HDC hdc;

    hdc = GetDC(hwnd);
    TextOut(hdc,

        x,
        y,

        Msg,
        strlen(Msg));


    ReleaseDC(hwnd, hdc);

}
void Println()
{
    x = 0;
    y += 20;
}

是的我知道关于这个主题还有其他问题,但是他们似乎都没有回答我的问题或解决我在尝试在子窗口上绘画时遇到的任何问题。

2 个答案:

答案 0 :(得分:2)

在我看来你在WndProc中创建了你的窗口,但它们没有被返回,所以当WM_CREATE返回时,在WndProc中创建的两个窗口最终都是NULL(AS只在WndProc中声明)。

也许您需要将这两者都设置为全局变量,例如使用GetDC(hEdit)来绘制它们。总的来说,它仍然看起来像一个奇怪的代码。

答案 1 :(得分:0)

在我看来,您想通过手动将文本绘制到控件中,将文本写入您使用id = IDC_MAIN_EDIT创建的编辑控件?

尝试

case WM_COMMAND:
    //Print("Hello");

    hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);   // get handle to edit window
    if (hEdit != NULL)   // did we get a handle to the edit window?
    {
       int len = GetWindowTextLength(hEdit);
       SendMessage(hEdit , EM_SETSEL, len, len);   // select end of contents
       SendMessage(hEdit , EM_REPLACESEL, 0, (LPARAM)"Hello");   // replace end with new textt
    }
    break;

并且编辑控件将为您绘制文本。

如果要手动将文本写入由您创建的窗口,请修改Print宏,如下所示:

#define Print(msg2) print_line(hwnd, msg2)