我想制作一个屏幕截图并将其显示在我的程序窗口中,但到目前为止我只能将屏幕设为白色。
我做错了什么?
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("screen") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
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) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("Digital Clock"),
WS_POPUP|WS_DLGFRAME|WS_VISIBLE, //WS_OVERLAPPEDWINDOW| WS_MAXIMIZE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, SW_MAXIMIZE);// iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL f24Hour, fSuppress ;
static HBRUSH hBrushRed ;
static int cxClient, cyClient ;
HDC hdc ;
PAINTSTRUCT ps ;
TCHAR szBuffer [2] ;
HGDIOBJ hMem; // HBITMAP hMem;
HDC compdc;
switch (message)
{
case WM_CREATE:
hBrushRed = CreateSolidBrush (RGB (255, 0, 0)) ;
keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0); //get screen snapshot into clipboard
OpenClipboard(NULL);
hMem = GetClipboardData(CF_BITMAP);
case WM_SETTINGCHANGE:
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
return 0 ;
case WM_TIMER:
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
compdc = CreateCompatibleDC(hdc);
SelectObject(compdc,hMem);
BitBlt(hdc,0,0,cxClient,cyClient,compdc,20,20,SRCCOPY);
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
DeleteObject (hBrushRed);
PostQuitMessage (0) ;
}
case WM_DESTROY:
DeleteObject (hBrushRed) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
答案 0 :(得分:3)
首先,我会避免像这样使用剪贴板 - 用户应该只有在明确剪切或复制后才能看到剪贴板中的更改。
相反,您应该直接捕获屏幕的内容。鉴于您使用原始Win32调用进行此操作,您首先要在WndProc中定义一些额外的变量:
static HBITMAP bmp;
static RECT r;
然后在你的WM_CREATE处理程序中,你有类似这样的代码来实际捕获屏幕:
{
// First get a DC to the entire screen.
HDC s = GetDC(NULL);
// Then get the size of the screen:
r.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
r.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
r.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
r.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
// Then create a bitmap to hold the picture of the screen:
bmp = CreateCompatibleBitmap(s, r.right, r.bottom);
// Create a memory DC and select that BMP into it:
HDC mem=CreateCompatibleDC(s);
HBITMAP old = (HBITMAP)SelectObject(mem, bmp);
// Copy the bits from the screen to our DC (and our BMP that's selected into it.
BitBlt(mem, 0, 0, r.right, r.bottom, s, 0, 0, SRCCOPY);
// Clean up:
SelectObject(mem, old);
DeleteDC(mem);
ReleaseDC(NULL, s);
}
break;
然后在你的WM_PAINT处理程序中,你有这样的代码将它绘制到你的窗口:
{
hdc = BeginPaint(hWnd, &ps);
// Create a compatible DC and select our BMP into it:
HDC mem=CreateCompatibleDC(hdc);
HBITMAP old = (HBITMAP)SelectObject(mem, bmp);
// Copy bits from our BMP to our window:
BitBlt(hdc, 0, 0, r.right, r.bottom, mem, 0, 0, SRCCOPY);
// Clean up:
SelectObject(hdc, old);
DeleteDC(mem);
EndPaint(hWnd, &ps);
break;
}