2016-03-02 142 views
1

我是新来的Windows API。使用一些对WINAPI教程提供Windows的示例代码:C++ WinApi将图像.jpg绘制到新窗口?

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); 
} 
+0

不按本能编码。相反,请阅读[评论]中提供给您的资源(http://stackoverflow.com/questions/35698324/winapi-create-window-child-windows-process-a-button-press#comment59074595_35698324)到您以前的问题。 – IInspectable

+0

我认为'Graphics'会试图摧毁当它超出范围时通过它的HDC。如果不是,那么当你在之后立即填充一个矩形时,你认为会是什么结果? –

+0

@MarkRansom:'Graphics'类不会破坏提供的'HDC'。 –

回答

4

您正处于正确的轨道上。使用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); 
} 
3

您必须初始化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(&image, 10, 10);足以描绘图像。一旦你画了图像,不要在其上画任何东西。

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