【问题标题】:C++ WinApi Draw image .jpg to new window?C ++ WinApi将图像.jpg绘制到新窗口?
【发布时间】:2016-03-02 18:01:57
【问题描述】:

我是 Windows API 的新手。使用 Winapi 教程中提供的一些 Windows 示例代码:

Graphics.DrawImage(Image*, const Rect) method

我正在寻找打开.jpg 图像并将其绘制到我创建的新窗口。问题是我不确定如何在现有窗口中使用VOID Example_DrawImage9(HDC hdc) 方法。我的第一直觉是在回调过程中的case WM_PAINT 内调用它,并从那里使用hdc,但图像不显示。我如何知道要提供的正确hdc?我应该在哪里调用该方法?

#include <windows.h>
#include "stdafx.h" 
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

//*************************************************** added for gdiplus
HWND hEdit;

//************************************************how do I use this method   with the window I have created below?
VOID Example_DrawImage9(HDC hdc){
    Graphics graphics(hdc); // Create an Image object.
    Image image(L"C:/Users/Me/Desktop/fuzz.jpg"); // Create a Pen object.
    Pen pen(Color(255, 255, 0, 0), 2); // Draw the original source image.
    graphics.DrawImage(&image, 10, 10); // Create a Rect object that specifies the destination of the image.
    Rect destRect(200, 50, 150, 75); // Draw the rectangle that bounds the image.
    graphics.DrawRectangle(&pen, destRect); // Draw the image.
    graphics.DrawImage(&image, destRect);
}
//*********************************************************************************************



LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = {}; 
    wc.lpfnWndProc = WindowProc; //attach this callback procedure
    wc.hInstance = hInstance; //handle to application instance
    wc.lpszClassName = CLASS_NAME; 
    RegisterClass(&wc); //register wc
    // Create the window.
    HWND hwnd = CreateWindowEx( 
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

                                        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
        );

    if (hwnd == NULL){
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
return 0;
}

//callback procedure for this window, takes in all the window details
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    switch (uMsg){
        case WM_DESTROY: 
            PostQuitMessage(0);
            return 0;

        case WM_PAINT:{
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            //***************************************************************
            //do we call DrawImage here? what do we need to pass as hdc?
            //Example_DrawImage9(HDC hdc);//?????????????
            //***************************************************************
            FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
            EndPaint(hwnd, &ps);
        }
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

【问题讨论】:

  • 不要凭直觉编码。相反,请阅读 a comment 中提供给您的资源到您之前的问题。
  • 我认为Graphics 在超出范围时会尝试破坏您传递的 HDC。如果不是,您认为之后立即填充一个矩形会产生什么结果?
  • @MarkRansom:Graphics 类不会破坏提供的HDC
  • @RemyLebeau 很高兴知道,谢谢。我在文档中都找不到任何指示。

标签: c++ winapi graphics window drawimage


【解决方案1】:

你在正确的轨道上。使用BeginPaint() 提供的HDC。并且不要忘记在使用之前初始化 GDI+。

#include <windows.h>
#include "stdafx.h" 
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib, "Gdiplus.lib")

void Example_DrawImage9(HDC hdc)
{
    Graphics graphics(hdc);
    // Create an Image object.
    Image image(L"C:/Users/Me/Desktop/fuzz.jpg");
    // Create a Pen object.
    Pen pen(Color(255, 255, 0, 0), 2);
    // Draw the original source image.
    graphics.DrawImage(&image, 10, 10);
    // Create a Rect object that specifies the destination of the image.
    Rect destRect(200, 50, 150, 75);
    // Draw the rectangle that bounds the image.
    graphics.DrawRectangle(&pen, destRect);
    // Draw the image.
    graphics.DrawImage(&image, destRect);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    ULONG_PTR token;
    GdiplusStartupInput input = {0};
    input.GdiplusVersion = 1;
    GdiplusStartup(&token, &input, NULL);

    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = {}; 
    wc.lpfnWndProc = &WindowProc; //attach this callback procedure
    wc.hInstance = hInstance; //handle to application instance
    wc.lpszClassName = CLASS_NAME; 
    RegisterClass(&wc); //register wc
    // Create the window.
    HWND hwnd = CreateWindowEx( 
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd != NULL)
    {
        ShowWindow(hwnd, nCmdShow);

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

    GdiplusShutdown(token);
    return 0;
}

//callback procedure for this window, takes in all the window details
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY: 
            PostQuitMessage(0);
            return 0;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
            Example_DrawImage9(hdc);
            EndPaint(hwnd, &ps);
            return 0;
        }
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

【讨论】:

    【解决方案2】:

    您必须初始化 GDI+,然后在退出前将其关闭。

    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
    {
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR gdiplusToken;
        Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    
        //...
    
        Gdiplus::GdiplusShutdown(gdiplusToken);
    
        return 0;
    }
    

    graphics.DrawImage(&amp;image, 10, 10); 足以绘制图像。绘制图像后,请勿在其上绘制任何其他内容。

    您可以在WM_PAINT 中使用Example_DrawImage9(hdc)。在绘制图像之前使用FillRect

    【讨论】:

      猜你喜欢
      • 2017-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      相关资源
      最近更新 更多