简体   繁体   中英

Painting a Win32 child window

Hello all I have been trying to paint to my child window outside of WM_PAINT and Instead of painting on the child window it paints off of the window onto the screen I think it may be because of the location of x and y but shouldn't point (0,0) be the top left of the child window not of my actual screen? Here is what the code I wrote to try to paint onto the child window:

#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;
}

Yes I know there are other questions concerning this topic but none of them seemed to answer my question or address any of the problems I have been experiencing while trying to paint on the child window.

It Seems to me you create your windows in WndProc, but they do not get returned, so both windows created in WndProc end up being NULL when WM_CREATE returns (AS the are only declared in WndProc).

Perhaps you need to set these both to globals, the use for example GetDC(hEdit) to draw to them. Overall it still looks like an odd bit of code.

It seems to me that you want to write text to the edit control you created with id= IDC_MAIN_EDIT by manually drawing the text into the control?

Try

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;

and the edit control will draw the text for you.

If you want to manually write the text to the window created by you modify the Print macro as follows:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM