C ++에서 snippingtool을 만들려고합니다. 이 코드를 통해 경계선없는 전체 화면 창을 만들 수있었습니다.
WindProc :
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch (message)
{
case WM_CHAR: //this is just for a program exit besides window's borders/taskbar
if (wparam==VK_ESCAPE)
{
DestroyWindow(hwnd);
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
}
창 만들기;
WNDCLASS windowClass={0};
windowClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.hCursor=LoadCursor(NULL, IDC_ARROW);
windowClass.hInstance=NULL;
windowClass.lpfnWndProc=WndProc;
windowClass.lpszClassName=TEXT("Window in Console"); //needs to be the same name
//when creating the window as well
windowClass.style=CS_HREDRAW | CS_VREDRAW;
//also register the class
if (!RegisterClass(&windowClass))
MessageBoxA(NULL, "Could not register class", "Error", MB_OK);
HWND windowHandle=CreateWindowA("Window in Console",
NULL,
WS_POPUP, //borderless
0, //x coordinate of window start point
0, //y start point
GetSystemMetrics(SM_CXSCREEN), //width of window
GetSystemMetrics(SM_CYSCREEN), //height of the window
NULL, //handles and such, not needed
NULL,
NULL,
NULL);
ShowWindow(windowHandle, SW_RESTORE);
이제 남은 일은 화면의 스크린 샷을 찍어 양식에 그리는 것입니다. 이 부분에서 실패합니다.
검색했을 때 처음에는 SetPixel 기능을 보았지만 양식을 그리는 데 30 분 정도 걸렸습니다. 아주 느리다. 그런 다음 사람들은 Device Context (내가 이해 한대로 메모리에있는 양식의 드로잉 데이터)를 사용하고 그 위에 그리면 훨씬 빠르게 창을 업데이트한다고 말했습니다. 그리고 여기 내가 한 일이 있습니다.
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HDC hdc = GetDC(windowHandle);
BitBlt(hdc, 0, 0, nScreenWidth, nScreenHeight, GetDC(NULL), 0, 0, SRCCOPY | CAPTUREBLT);
UpdateWindow(windowHandle);
ShowWindow(windowHandle, SW_RESTORE);
UpdateWindow(windowHandle);
짐작할 수 있듯이 작동하지 않았습니다. 내 양식은 빈 흰색입니다. WindProc의 WM_PAINT 메시지에 이것을 작성해야하는지 여부를 이해할 수 없습니다. 나는 이것에 대해 많은 변형을 시도했고 실제로 한 지점이 효과가 있었지만 무언가를 변경했을 때 작동을 멈 췄고 다시 작동하지 못했습니다 ...
감사합니다.
의견을 보내 주셔서 감사합니다. WM_PAINT 메시지에 대해 좀 더 조사했습니다. 그리고이 황금 문서를 찾았습니다.
http://www.winprog.org/tutorial/bitmaps.html
원본 게시물의 내 코드는 동일하게 유지되며 두 가지만 추가했습니다.
1- 화면의 스크린 샷을 찍고 저장;
(여기에서 확인 :
Windows 애플리케이션에서 스크린 샷을 찍으려면 어떻게해야합니까? )
// get the device context of the screen
HDC hScreenDC = GetDC(NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
// hBitmap is a HBITMAP that i declared globally to use within WM_PAINT
// maybe worth checking these are positive values
hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP) SelectObject(hMemoryDC, hOldBitmap);
// clean up
DeleteDC(hMemoryDC);
ReleaseDC(NULL,hScreenDC);
// now your image is held in hBitmap. You can save it or do whatever with it
2- WM_PAINT를 통한 페인팅 :
switch (message)
{
case WM_PAINT:{
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
BITMAP bm;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap);
GetObject(hBitmap, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
}
return 0;
나는 GDI, 창에 완전히 익숙하지 않습니다. 나는 여기저기서 찾은 조각을 약간 으깨어 놓았지만 작동합니다 xd
도움을 주셔서 감사합니다.
편집 : 또한 간단한 정보입니다. 디스플레이 설정에 약간의 배율이있는 경우 스크린 샷도 배율이 조정됩니다. 이것이 의미하는 바는 125 % 스케일링이있는 경우 스크린 샷이 실제 전체 화면이 아니라는 것입니다. 이를 방지하려면 매니페스트 파일이 필요합니다.
https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests
우리가 찾고있는 설정은 DPI 인식입니다. 여기에 내 매니페스트 파일이 있습니다.
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
내 .rc 파일 :
#include "winuser.h"
1 RT_MANIFEST scanner.exe.manifest
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다