From f2c217a6fb643ed2b8e3a4e548a0ada993838e52 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 25 Oct 2008 11:10:20 +0900 Subject: [PATCH] [17/19] paint: Add [Cut], [Copy] and [Paste] commands --- programs/paint/bitmap.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++ programs/paint/main.h | 2 + programs/paint/paint.c | 93 +++++++++++++++++++++++++++++- 3 files changed, 237 insertions(+), 3 deletions(-) diff --git a/programs/paint/bitmap.c b/programs/paint/bitmap.c index f346c3b..108b9a8 100644 --- a/programs/paint/bitmap.c +++ b/programs/paint/bitmap.c @@ -517,3 +517,148 @@ HBITMAP BM_Copy(HBITMAP hbm) { return (HBITMAP)CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG); } + +HGLOBAL BM_Pack(HBITMAP hbm) +{ + BOOL f; + DWORD dwError; + HGLOBAL hPack; + BITMAPINFOEX bi; + DWORD cb, cbPack, cColors, cbColors; + HDC hDC; + LPVOID pPack, pBits; + BITMAP bm; + BITMAPINFOHEADER *pbmih = &bi.bmiHeader; + + if (!GetObject(hbm, sizeof(BITMAP), &bm)) + return FALSE; + + ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER)); + pbmih->biSize = sizeof(BITMAPINFOHEADER); + pbmih->biWidth = bm.bmWidth; + pbmih->biHeight = bm.bmHeight; + pbmih->biPlanes = 1; + pbmih->biBitCount = bm.bmBitsPixel; + pbmih->biCompression = BI_RGB; + pbmih->biSizeImage = bm.bmWidthBytes * bm.bmHeight; + + if (bm.bmBitsPixel < 16) + cColors = 1 << bm.bmBitsPixel; + else + cColors = 0; + cbColors = cColors * sizeof(RGBQUAD); + + cb = pbmih->biSize + cbColors; + cbPack = cb + pbmih->biSizeImage; + + hPack = GlobalAlloc(GMEM_DDESHARE|GHND, cbPack); + pPack = GlobalLock(hPack); + if (pPack == NULL) + return NULL; + + f = FALSE; + dwError = 0; + pBits = HeapAlloc(GetProcessHeap(), 0, pbmih->biSizeImage); + if (pBits != NULL) + { + hDC = GetDC(NULL); + if (hDC != NULL) + { + if (GetDIBits(hDC, hbm, 0, bm.bmHeight, pBits, (BITMAPINFO*)&bi, + DIB_RGB_COLORS)) + { + CopyMemory(pPack, &bi, sizeof(BITMAPINFOHEADER)); + CopyMemory((LPBYTE)pPack + sizeof(BITMAPINFOHEADER), &bi.bmiColors, cbColors); + CopyMemory((LPBYTE)pPack + cb, pBits, pbmih->biSizeImage); + f = TRUE; + } + else + dwError = GetLastError(); + ReleaseDC(NULL, hDC); + } + else + dwError = GetLastError(); + + HeapFree(GetProcessHeap(), 0, pBits); + } + + GlobalUnlock(hPack); + if (!f) + { + GlobalFree(hPack); + hPack = NULL; + } + + SetLastError(dwError); + return hPack; +} + +HBITMAP BM_Unpack(HGLOBAL hPack) +{ + HBITMAP hbm; + DWORD dwError; + BITMAPINFOEX bi; + DWORD cb, cColors, cbColors; + HDC hDC, hMemDC; + LPVOID pPack, pBits; + BITMAPINFOHEADER *pbmih = &bi.bmiHeader; + + pPack = GlobalLock(hPack); + if (pPack == NULL) + return NULL; + + CopyMemory(pbmih, pPack, sizeof(BITMAPINFOHEADER)); + pbmih->biSizeImage = WIDTHBYTES(pbmih->biWidth * pbmih->biBitCount) * + abs(pbmih->biHeight); + if (pbmih->biClrUsed != 0) + cColors = pbmih->biClrUsed; + else if (pbmih->biBitCount < 16) + cColors = 1 << pbmih->biBitCount; + else + cColors = 0; + + cbColors = cColors * sizeof(RGBQUAD); + cb = pbmih->biSize + cbColors; + CopyMemory(&bi, pPack, cb); + + hbm = NULL; + dwError = 0; + hDC = GetDC(NULL); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbm = CreateDIBSection(hMemDC, (BITMAPINFO*)&bi, DIB_RGB_COLORS, + &pBits, NULL, 0); + if (hbm != NULL) + { + CopyMemory(pBits, (LPBYTE)pPack + cb, pbmih->biSizeImage); + + if (SetDIBits(hMemDC, hbm, 0, abs(bi.bmiHeader.biHeight), + pBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) + { + ; + } + else + { + dwError = GetLastError(); + DeleteObject(hbm); + hbm = NULL; + } + } + else + dwError = GetLastError(); + + DeleteDC(hMemDC); + } + else + dwError = GetLastError(); + } + else + dwError = GetLastError(); + + GlobalUnlock(hPack); + SetLastError(dwError); + return hbm; +} diff --git a/programs/paint/main.h b/programs/paint/main.h index f1b62c6..b36cab3 100644 --- a/programs/paint/main.h +++ b/programs/paint/main.h @@ -175,3 +175,5 @@ HBITMAP BM_CreateRotated90Degree(HWND hWnd, HBITMAP hbm, SIZE siz); HBITMAP BM_CreateRotated180Degree(HWND hWnd, HBITMAP hbm, SIZE siz); HBITMAP BM_CreateRotated270Degree(HWND hWnd, HBITMAP hbm, SIZE siz); HBITMAP BM_Copy(HBITMAP hbm); +HGLOBAL BM_Pack(HBITMAP hbm); +HBITMAP BM_Unpack(HGLOBAL hPack); diff --git a/programs/paint/paint.c b/programs/paint/paint.c index 2e6f0e6..ce65f4a 100644 --- a/programs/paint/paint.c +++ b/programs/paint/paint.c @@ -432,17 +432,104 @@ VOID PAINT_EditRepeat(VOID) VOID PAINT_EditCut(VOID) { - NotSupportedYet(); + HBITMAP hbm; + HGLOBAL hPack; + if (Globals.fSelect) + { + Selection_TakeOff(); + hbm = Globals.hbmSelect; + Globals.hbmSelect = NULL; + Globals.fSelect = FALSE; + hPack = BM_Pack(hbm); + DeleteObject(hbm); + if (OpenClipboard(Globals.hCanvasWnd)) + { + EmptyClipboard(); + SetClipboardData(CF_DIB, hPack); + CloseClipboard(); + } + InvalidateRect(Globals.hCanvasWnd, NULL, FALSE); + UpdateWindow(Globals.hCanvasWnd); + } } VOID PAINT_EditCopy(VOID) { - NotSupportedYet(); + HBITMAP hbm; + HGLOBAL hPack; + + if (Globals.fSelect) + { + hbm = Selection_CreateBitmap(); + hPack = BM_Pack(hbm); + DeleteObject(hbm); + if (OpenClipboard(Globals.hCanvasWnd)) + { + EmptyClipboard(); + SetClipboardData(CF_DIB, hPack); + CloseClipboard(); + } + InvalidateRect(Globals.hCanvasWnd, NULL, FALSE); + UpdateWindow(Globals.hCanvasWnd); + } } VOID PAINT_EditPaste(VOID) { - NotSupportedYet(); + HGLOBAL hPack; + HBITMAP hbm; + BITMAP bm; + SIZE siz; + + Selection_Land(); + hPack = NULL; + if (OpenClipboard(Globals.hCanvasWnd)) + { + hPack = GetClipboardData(CF_DIB); + CloseClipboard(); + } + if (hPack == NULL) + return; + + Globals.iToolPrev = Globals.iToolSelect; + Globals.iToolSelect = TOOL_BOXSELECT; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + + hbm = BM_Unpack(hPack); + if (hbm != NULL) + { + Globals.fSelect = TRUE; + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbm; + GetObject(Globals.hbmSelect, sizeof(BITMAP), &bm); + if (Globals.sizImage.cx < bm.bmWidth || + Globals.sizImage.cy < bm.bmHeight) + { + siz.cx = bm.bmWidth; + siz.cy = bm.bmHeight; + Canvas_Resize(Globals.hCanvasWnd, siz); + Globals.sizImage = siz; + Globals.pt0.x = 0; + Globals.pt0.y = 0; + Globals.pt1.x = bm.bmWidth; + Globals.pt1.y = bm.bmHeight; + } + else + { + Globals.pt0.x = Globals.xScrollPos / Globals.nZoom; + Globals.pt0.y = Globals.yScrollPos / Globals.nZoom; + Globals.pt1.x = Globals.pt0.x + bm.bmWidth; + Globals.pt1.y = Globals.pt0.y + bm.bmHeight; + } + + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } + else + ShowLastError(); } VOID PAINT_EditDelete(VOID) -- 1.6.0.2