有几种方法可以在 Windows 中获取设备上下文的句柄。例如,WM_PAINT
处理程序通常会调用BeginPaint
以获取设备上下文,将内容更新到窗口,然后调用EndPaint
. 在无法使用BeginPaint
和EndPaint
无法使用的情况下(例如,在 WM_PAINT 消息之外),您可以使用GetDC
更新窗口,然后调用ReleaseDC
.
设备上下文返回BeginPaint
并GetDC
允许您直接绘制到窗口。但是,有时您想直接绘制到位图。在这种情况下,您将调用CreateCompatibleDC
,选择要绘制的位图,进行绘制,然后调用DeleteDC
。
在您的情况下,您正在寻找类似于以下内容的内容:
HDC dc = GetDC(windowHandle);
cairo_win32_surface_create(dc);
ReleaseDC(windowHandle, dc);
如果您不想在此阶段创建窗口(因为您只是保存图像),您可能可以使用桌面窗口来获取设备上下文。
HWND windowHandle = GetDesktopWindow();
HDC dc = GetDC(windowHandle);
cairo_win32_surface_create(dc);
ReleaseDC(windowHandle, dc);
还有其他调用可用于获取或创建设备上下文。您可以在此处找到这些和相关功能的列表
创建和使用窗口涉及更多内容,因此我将为您提供基本步骤和一些示例代码,您可以使用它们来玩弄。要创建和使用窗口...
- 注册一个窗口类
RegisterClass
CreateWindow
使用or创建窗口CreateWindowEx
- 通过调用使用消息泵处理消息
GetMessage
,TranslateMessage
以及DispatchMessage
此外,您将必须实现一个函数来处理窗口消息的处理,例如WM_PAINT
.
注意:以下代码未经测试,但应该是正确的。
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_PAINT)
{
HDC dc;
PAINTSTRUCT ps;
dc = BeginPaint(hwnd, &ps);
// do your drawing here
EndPaint(hwnd, &ps);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szClassName[] = TEXT("DrawSurfaceClass");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
///////////////////////////////////////////////////////////
// Register a window "class"
///////////////////////////////////////////////////////////
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground =(HBRUSH)COLOR_WINDOW;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
if(!RegisterClass(&wndclass))
{
// error
return 1;
}
///////////////////////////////////////////////////////////
// Create the window and display it (if iCmdShow says so)
///////////////////////////////////////////////////////////
hwnd = CreateWindow(
szAppName,
TEXT("Draw Surface"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
///////////////////////////////////////////////////////////
// Run the message pump so the window proc recieves events
///////////////////////////////////////////////////////////
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}