Compare commits

...

4 commits

Author SHA1 Message Date
snow flurry 94989c680a Grabby: Write the screenshot to %TEMP%
Means I don't have to ignore *.bmp in the repo. I'll probably make this user-configurable, once we have a configuration system in place.

git-svn-id: svn://vcs.sdm.2ki.xyz/Grabby/trunk@14 27729192-006e-004d-b9b5-06fbd0ef7001
2024-02-15 07:32:20 +00:00
snow flurry dc07b5e612 Bitmap.c: Avoid calling GetProcessHeap so much
Not really a major functionality/performance change, it just makes me feel better.

git-svn-id: svn://vcs.sdm.2ki.xyz/Grabby/trunk@13 27729192-006e-004d-b9b5-06fbd0ef7001
2024-02-15 05:55:27 +00:00
snow flurry 7d1c91401f Bitmap.c: Cleanup some memory management
git-svn-id: svn://vcs.sdm.2ki.xyz/Grabby/trunk@12 27729192-006e-004d-b9b5-06fbd0ef7001
2024-02-15 05:51:35 +00:00
snow flurry d64803c1a9 OverlayWndProc: Fix rendering issue, allow Esc to cancel
git-svn-id: svn://vcs.sdm.2ki.xyz/Grabby/trunk@11 27729192-006e-004d-b9b5-06fbd0ef7001
2024-02-15 05:40:23 +00:00
4 changed files with 54 additions and 15 deletions

View file

@ -36,6 +36,9 @@ void
DeleteScreen(Screen *scrn) DeleteScreen(Screen *scrn)
{ {
if (scrn) { if (scrn) {
if (scrn->hOldObj) SelectObject(scrn->hdcBitmap, scrn->hOldObj);
if (scrn->hBitmap) DeleteObject(scrn->hBitmap);
if (scrn->hScreenRgn) DeleteObject((HGDIOBJ) scrn->hScreenRgn); if (scrn->hScreenRgn) DeleteObject((HGDIOBJ) scrn->hScreenRgn);
if (scrn->hdcBitmap) DeleteDC(scrn->hdcBitmap); if (scrn->hdcBitmap) DeleteDC(scrn->hdcBitmap);
if (scrn->hdcScreen) DeleteDC(scrn->hdcScreen); if (scrn->hdcScreen) DeleteDC(scrn->hdcScreen);
@ -57,9 +60,13 @@ PFULLBMPHDR
GenerateBitmapInfo(Screen *scrn, GenerateBitmapInfo(Screen *scrn,
BITMAP *bmp) BITMAP *bmp)
{ {
PFULLBMPHDR pBmpHdr = HeapAlloc(GetProcessHeap(), // GDI seems to modify the DWORD after the info header, even if we
// don't need a palette (>8 bit BMPs). Thus, an extra RGBQUAD just
// to be safe.
HANDLE hHeap = GetProcessHeap();
PFULLBMPHDR pBmpHdr = HeapAlloc(hHeap,
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
sizeof(struct _FULLBMPHDR)); sizeof(struct _FULLBMPHDR) + sizeof(RGBQUAD));
RECT rcScrn = {0}; RECT rcScrn = {0};
WORD cClrBits = (WORD)(bmp->bmPlanes * bmp->bmBitsPixel); WORD cClrBits = (WORD)(bmp->bmPlanes * bmp->bmBitsPixel);
DWORD hdrSize; DWORD hdrSize;
@ -67,6 +74,7 @@ GenerateBitmapInfo(Screen *scrn,
if (!pBmpHdr) return NULL; if (!pBmpHdr) return NULL;
if (!GetRgnBox(scrn->hScreenRgn, &rcScrn)) { if (!GetRgnBox(scrn->hScreenRgn, &rcScrn)) {
HeapFree(hHeap, 0, pBmpHdr);
return NULL; return NULL;
} }
@ -156,7 +164,8 @@ WriteRegionToFile(Screen *scrn,
LPTSTR fname) LPTSTR fname)
{ {
BITMAP bmp = {0}; // hBitmap's metadata BITMAP bmp = {0}; // hBitmap's metadata
HANDLE hOutFile = NULL; // Output .bmp HANDLE hOutFile = NULL, // Output .bmp
hHeap = GetProcessHeap();
LPBYTE lpBits = NULL; // Actual bitmap bits LPBYTE lpBits = NULL; // Actual bitmap bits
HDC hdcRgn = NULL; // HDC for defined region HDC hdcRgn = NULL; // HDC for defined region
@ -236,7 +245,7 @@ WriteRegionToFile(Screen *scrn,
goto cleanup; goto cleanup;
} }
lpBits = HeapAlloc(GetProcessHeap(), lpBits = HeapAlloc(hHeap,
0, 0,
pHdr->info.biSizeImage); pHdr->info.biSizeImage);
if (!lpBits) { if (!lpBits) {
@ -245,7 +254,7 @@ WriteRegionToFile(Screen *scrn,
} }
if (pHdr->info.biBitCount <= 8) { if (pHdr->info.biBitCount <= 8) {
pbmi = HeapAlloc(GetProcessHeap(), pbmi = HeapAlloc(hHeap,
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
sizeof(BITMAPINFOHEADER) + sizeof(BITMAPINFOHEADER) +
(pHdr->info.biClrUsed * sizeof(RGBQUAD))); (pHdr->info.biClrUsed * sizeof(RGBQUAD)));
@ -329,18 +338,16 @@ cleanup:
} }
} }
if (lpBits) HeapFree(GetProcessHeap(), 0, lpBits); if (lpBits) HeapFree(hHeap, 0, lpBits);
// In case our bits are <= 8, pbmi will be an actual heap-alloc'd // In case our bits are <= 8, pbmi will be an actual heap-alloc'd
// pointer. Let's make sure to handle that. // pointer. Let's make sure to handle that.
if (pbmi && pbmi != (PBITMAPINFO) &pHdr->info) HeapFree(GetProcessHeap(), 0, pbmi); if (pbmi && pbmi != (PBITMAPINFO) &pHdr->info) HeapFree(hHeap, 0, pbmi);
if (pHdr) HeapFree(GetProcessHeap(), 0, pHdr); if (pHdr) HeapFree(hHeap, 0, pHdr);
if (scrn->hOldObj) SelectObject(scrn->hdcBitmap, scrn->hOldObj);
if (hOldObj) SelectObject(hdcRgn, hOldObj); if (hOldObj) SelectObject(hdcRgn, hOldObj);
if (hRgnBitmap) DeleteObject(hRgnBitmap); if (hRgnBitmap) DeleteObject(hRgnBitmap);
if (scrn->hBitmap) DeleteObject(scrn->hBitmap);
if (hdcRgn) DeleteDC(hdcRgn); if (hdcRgn) DeleteDC(hdcRgn);

View file

@ -59,8 +59,14 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
LPTSTR lpCmdLine, LPTSTR lpCmdLine,
int nCmdShow) int nCmdShow)
{ {
SYSTEMTIME stNow = {0};
RECT capRegion = {0}; RECT capRegion = {0};
Screen *scrn = CreateScreen(); Screen *scrn = CreateScreen();
#define OUTPUT_DIR_LEN 96
TCHAR szOutputDir[OUTPUT_DIR_LEN + 1];
#define FULL_OUT_PATH_LEN OUTPUT_DIR_LEN + 24
TCHAR szFullOutPath[FULL_OUT_PATH_LEN + 1];
HRESULT hRes;
if (!scrn) { if (!scrn) {
Die("Couldn't get screen information"); Die("Couldn't get screen information");
@ -80,8 +86,28 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
GetChosenRect(&capRegion); GetChosenRect(&capRegion);
if (!GetTempPath(OUTPUT_DIR_LEN, szOutputDir)) {
Die("Couldn't get temporary directory");
}
if (WriteRegionToFile(scrn, &capRegion, _T("test.bmp")) == -1) { GetLocalTime(&stNow);
hRes = StringCchPrintf(szFullOutPath,
FULL_OUT_PATH_LEN,
"%s\\scrn_%04d%02d%02d_%02d%02d%02d.bmp",
szOutputDir,
stNow.wYear,
stNow.wMonth,
stNow.wDay,
stNow.wHour,
stNow.wMinute,
stNow.wSecond);
if (FAILED(hRes)) {
Die("Couldn't create screenshot file path");
}
if (WriteRegionToFile(scrn, &capRegion, szFullOutPath) == -1) {
Die("Couldn't grab region of the screen"); Die("Couldn't grab region of the screen");
} }

View file

@ -187,7 +187,11 @@ OverlayWndProc(HWND hWnd,
(ptCur.y != ptStart.y)) (ptCur.y != ptStart.y))
{ {
RECT rcPrevDmg = POINT2RECT(ptStart, ptPrev); RECT rcPrevDmg = POINT2RECT(ptStart, ptPrev);
// InvalidateRect(hWnd, &rcCurDmg, TRUE); // Expand out a little bit to contain the focus rect
rcPrevDmg.left--;
rcPrevDmg.right++;
rcPrevDmg.top--;
rcPrevDmg.bottom++;
InvalidateRect(hWnd, &rcPrevDmg, TRUE); InvalidateRect(hWnd, &rcPrevDmg, TRUE);
} }
@ -211,8 +215,10 @@ OverlayWndProc(HWND hWnd,
} }
break; break;
case WM_KEYUP: case WM_KEYUP:
// TODO: Escape if (wParam != VK_ESCAPE) {
break; break;
}
/* PASSTHRU */
case WM_RBUTTONUP: case WM_RBUTTONUP:
// We treat right click as Escape // We treat right click as Escape
PostQuitMessage(1); PostQuitMessage(1);

View file

@ -16,4 +16,4 @@
#include <stdio.h> #include <stdio.h>
#include <tchar.h> #include <tchar.h>
// TODO: reference additional headers your program requires here #include <Strsafe.h>