TNB Library
TnbBitmapHandle.h
[詳解]
1#pragma once
15#include "TnbPointerHandle.h"
16#ifndef _WIN32_WCE
17 #pragma comment(lib, "gdi32.lib")
18#else
19 #define LR_CREATEDIBSECTION 0
20#endif
21
22
23
24//TNB Library
25namespace TNB
26{
27
28
29
30#ifndef _TnbDOXYGEN //Document作成用シンボル
31
33struct TPhDeleteBitmapHandle
34{
35 void operator()(HBITMAP h)
36 {
37 #ifdef _DEBUG
38 if ( ::GetObjectType(h) == NULL )
39 {
40 ASSERT0( false, "~CBitmapHandle", "先に HBITMAPが破棄されてしまっています。" );
41 }
42 else if ( ! ::DeleteObject(h) )
43 {
44 ASSERT1( false, "~CBitmapHandle", "HBITMAP の破棄に失敗しました。\ncode = %d", ::GetLastError() );
45 }
46 #else
47 ::DeleteObject(h);
48 #endif
49 }
50};
51
52#endif // _TnbDOXYGEN
53
54
55
101class CBitmapHandle : public CPointerHandleBaseT<HBITMAP, TPhDeleteBitmapHandle, NULL>
102{
104 DEFSUPER(_super);
105public:
106
112 {
113 }
114
121 CBitmapHandle(const CBitmapHandle& other) : _super(other)
122 {
123 }
124
130 CBitmapHandle(HBITMAP P) : _super(P)
131 {
132 }
133
145 CBitmapHandle(UINT uBitmapResourceId, int cx = 0, int cy = 0, UINT fuLoad = LR_CREATEDIBSECTION)
146 {
147 _super::operator=(Load(uBitmapResourceId, cx, cy, fuLoad));
148 }
149
160 CBitmapHandle(LPCTSTR lpszFile, int cx = 0, int cy = 0, UINT fuLoad = LR_CREATEDIBSECTION)
161 {
162 _super::operator=(Load(lpszFile, cx, cy, fuLoad));
163 }
164
165 #ifdef __AFX_H__
176 CBitmapHandle(const CString& strFile, int cx = 0, int cy = 0, UINT fuLoad = LR_CREATEDIBSECTION)
177 {
178 _super::operator=(Load(strFile.operator LPCTSTR(), cx, cy, fuLoad));
179 }
180 #endif
181
189 bool GetSize(SIZE& _size) const
190 {
191 BITMAP bm;
192 if ( ::GetObject(*this, sizeof(BITMAP), &bm) > 0 )
193 {
194 _size.cx = bm.bmWidth;
195 _size.cy = bm.bmHeight;
196 return true;
197 }
198 _GetLastError("GetObject");
199 _size.cx = 0;
200 _size.cy = 0;
201 return false;
202 }
203
211 HBITMAP Detach(void)
212 {
213 if ( IsNull() ) { return NULL; }
214 #ifndef _WIN32_WCE
215 HBITMAP h = static_cast<HBITMAP>(::CopyImage(*this, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION));
216 #else
217 RGBQUAD* pRgb;
218 HBITMAP h = Create32bitDibSection(*this, pRgb);
219 #endif
220 Null();
221 return h;
222 }
223
230 void SetClone(HBITMAP hBmp)
231 {
232 #ifndef _WIN32_WCE
233 _super::operator=(static_cast<HBITMAP>(::CopyImage(hBmp, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION)));
234 #else
235 RGBQUAD* pRgb;
237 #endif
238 }
239
249 bool Draw(HDC hdc, int x = 0, int y = 0) const
250 {
251 HBITMAP h = *this;
252 return Draw(hdc, h, x, y);
253 }
254
263 DWORD Save(LPCTSTR lpszFileName, WORD bitsPixel = 0)
264 {
265 return Save(lpszFileName, *this, bitsPixel);
266 }
267
268
269 //-----------------
270
271
281 static HBITMAP Create32bitDibSection(HBITMAP hbm, RGBQUAD*& _pRgb, BITMAPINFOHEADER* pHeader = NULL)
282 {
283 BITMAP bm;
284 if ( ! ::GetObject(hbm, sizeof(BITMAP), &bm) )
285 {
286 return NULL;
287 }
288 HDC hdcSrc = ::CreateCompatibleDC(NULL);
289 HDC hdcDst = ::CreateCompatibleDC(NULL);
290 HGDIOBJ hbmOld = ::SelectObject(hdcSrc, hbm);
291 BITMAPINFOHEADER bmi;
292 Zero(bmi);
293 bmi.biSize = sizeof(BITMAPINFOHEADER);
294 bmi.biWidth = bm.bmWidth;
295 bmi.biHeight = bm.bmHeight;
296 bmi.biPlanes = 1;
297 bmi.biBitCount = 32;
298 bmi.biCompression = BI_RGB;
299 HBITMAP hbmNew = ::CreateDIBSection(hdcSrc, reinterpret_cast<BITMAPINFO*>(&bmi), DIB_RGB_COLORS, reinterpret_cast<void **>(&_pRgb), NULL, 0);
300 HGDIOBJ hbmOld2 = ::SelectObject(hdcDst, hbmNew);
301 ::BitBlt(hdcDst, 0, 0, bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, SRCCOPY);
302 ::SelectObject(hdcDst, hbmOld2);
303 ::SelectObject(hdcSrc, hbmOld);
304 ::DeleteDC(hdcSrc);
305 ::DeleteDC(hdcDst);
306 if ( pHeader != NULL )
307 {
308 *pHeader = bmi;
309 }
310 return hbmNew;
311 }
312
324 static HBITMAP Load(UINT uBitmapResourceId, int cx = 0, int cy = 0, UINT fuLoad = LR_CREATEDIBSECTION)
325 {
326 HINSTANCE hIns = GetInstanceHandleByTnb(EI_Bitmap);
327 LPCTSTR lpId = MAKEINTRESOURCE(uBitmapResourceId);
328 return static_cast<HBITMAP>(::LoadImage(hIns, lpId, IMAGE_BITMAP, cx, cy, fuLoad));
329 }
330
341 static HBITMAP Load(LPCTSTR lpszFileName, int cx = 0, int cy = 0, UINT fuLoad = LR_CREATEDIBSECTION)
342 {
343 if ( lpszFileName == NULL || *lpszFileName == 0 )
344 {
345 return NULL;
346 }
347 HINSTANCE hIns = GetInstanceHandleByTnb(EI_Bitmap);
348 #ifndef _WIN32_WCE
349 return static_cast<HBITMAP>(::LoadImage(hIns, lpszFileName, IMAGE_BITMAP, cx, cy, fuLoad | LR_LOADFROMFILE));
350 #else
351 return static_cast<HBITMAP>(::LoadBitmap(hIns, lpszFileName));
352 #endif
353 }
354
365 static HBITMAP LoadOem(UINT uOemBitmapResourceId, int cx = 0, int cy = 0, UINT fuLoad = 0)
366 {
367 LPCTSTR lpId = MAKEINTRESOURCE(uOemBitmapResourceId);
368 #ifndef _WIN32_WCE
369 fuLoad |= LR_SHARED;
370 #endif
371 return static_cast<HBITMAP>(::LoadImage(NULL, lpId, IMAGE_BITMAP, cx, cy, fuLoad));
372 }
373
384 static bool Draw(HDC hdc, HBITMAP hBmp, int x = 0, int y = 0)
385 {
386 #ifndef _WIN32_WCE
387 LPARAM l = reinterpret_cast<LPARAM>(hBmp);
388 bool r = !! ::DrawState(hdc, NULL, NULL, l, 0, x, y, 0, 0, DST_BITMAP | DSS_NORMAL);
389 return r;
390 #else
391 BITMAP bm;
392 if ( ::GetObject(hBmp, sizeof(BITMAP), &bm) > 0 )
393 {
394 HDC tempDC = ::CreateCompatibleDC(hdc);
395 HGDIOBJ oldBmp = ::SelectObject(tempDC, hBmp);
396 bool r =!! ::BitBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, tempDC, 0, 0, SRCCOPY);
397 ::SelectObject(tempDC, oldBmp);
398 ::DeleteDC(tempDC);
399 return r;
400 }
401 return false;
402 #endif
403 }
404
414 #ifndef _WIN32_WCE
415 static DWORD SaveMemory(CWorkMem& _save, HBITMAP bmp, WORD bitsPixel = 0)
416 {
417 BITMAP bp;
418 if ( ::GetObject(bmp, sizeof(BITMAP), &bp) <= 0 )
419 {
420 return _GetLastError("GetObject");
421 }
422 // BITMAP情報生成
423 BITMAPFILEHEADER fh = { 0 };
424 LONG paletCount = 0;
425 fh.bfType = 'B' + 'M' * 256;
426 fh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
427 CWorkMem workHead(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
428 BITMAPINFOHEADER* pih = (BITMAPINFOHEADER*)workHead.Ref();
429 ZeroMemory(pih, workHead.GetSize());
430 pih->biSize = sizeof(BITMAPINFOHEADER);
431 pih->biWidth = bp.bmWidth;
432 pih->biHeight = bp.bmHeight;
433 pih->biPlanes = bp.bmPlanes;
434 pih->biBitCount = (bitsPixel == 0) ? bp.bmBitsPixel : bitsPixel;
435 pih->biCompression = BI_RGB;
436 pih->biSizeImage = bp.bmWidthBytes * bp.bmHeight;
437 switch(pih->biBitCount)
438 {
439 case 1:
440 paletCount = 2;
441 pih->biSizeImage = (((pih->biWidth / 4) + 3) & 0xfffffffc) * pih->biHeight;
442 fh.bfOffBits += (sizeof(RGBQUAD) * 2);
443 break;
444 case 4:
445 paletCount = 16;
446 pih->biSizeImage = (((pih->biWidth / 2) + 3) & 0xfffffffc) * pih->biHeight;
447 fh.bfOffBits += (sizeof(RGBQUAD) * 16);
448 break;
449 case 8:
450 paletCount = 256;
451 pih->biSizeImage = ((pih->biWidth + 3) & 0xfffffffc) * pih->biHeight;
452 fh.bfOffBits += (sizeof(RGBQUAD) * 256);
453 break;
454 case 16:
455 paletCount = 0;
456 pih->biSizeImage = ((pih->biWidth * 2 + 3) & 0xfffffffc) * pih->biHeight;
457 break;
458 case 24:
459 paletCount = 0;
460 pih->biSizeImage = ((pih->biWidth * 3 + 3) & 0xfffffffc) * pih->biHeight;
461 break;
462 case 32:
463 paletCount = 0;
464 pih->biSizeImage = pih->biWidth * 4 * pih->biHeight;
465 break;
466 default:
467 return ERROR_INVALID_PARAMETER;
468 }
469 // 画像データ出力
470 CWorkMem data(pih->biSizeImage + 256 * sizeof(RGBQUAD));
471 HDC dc = ::CreateCompatibleDC(NULL);
472 HGDIOBJ old = ::SelectObject(dc, bmp);
473 int r = ::GetDIBits(dc, bmp, 0, pih->biHeight, data.Ref(), reinterpret_cast<LPBITMAPINFO>(pih), DIB_RGB_COLORS);
474 if ( r == 0 )
475 {
476 return _GetLastError("GetDIBits");
477 }
478 ::SelectObject(dc, old);
479 ::DeleteDC(dc);
480 fh.bfSize = fh.bfOffBits + pih->biSizeImage;
481 // ヘッダ
482 LPCVOID P1 = &fh;
483 size_t l1 = sizeof(fh);
484 // BITMAP情報
485 LPCVOID P2 = pih;
486 size_t l2 = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * paletCount;
487 // 画像データ
488 LPCVOID P3 = data.Ref();
489 size_t l3 = pih->biSizeImage;
490 // 出力
491 _save.Resize(l1 + l2 + l3);
492 BYTE* B = _save.Ref();
493 MemCopy(B, P1, l1);
494 B += l1;
495 MemCopy(B, P2, l2);
496 B += l2;
497 MemCopy(B, P3, l3);
498 B += l3;
499 return ERROR_SUCCESS;
500 }
501 #else
502 static DWORD SaveMemory(CWorkMem& _save, HBITMAP bmp, WORD bitsPixel = 0)
503 {
504 RGBQUAD* pRgb;
505 BITMAPINFOHEADER header;
506 BITMAPFILEHEADER fh;
507 ZeroMemory(&fh, sizeof(fh));
508 fh.bfType = 'B' + 'M' * 256;
509 fh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
510 HBITMAP hTmp = Create32bitDibSection(bmp, pRgb, &header);
511 if ( hTmp == NULL )
512 {
513 return _GetLastError("GetObject");
514 }
515 size_t len = header.biWidth * 4 * header.biHeight;
516 fh.bfSize = fh.bfOffBits + len;
517 // ヘッダ
518 LPCVOID P1 = &fh;
519 size_t l1 = sizeof(fh);
520 // BITMAP情報
521 LPCVOID P2 = &header;
522 size_t l2 = sizeof(header);
523 // 画像データ
524 LPCVOID P3 = pRgb;
525 size_t l3 = len;
526 // 出力
527 _save.Resize(l1 + l2 + l3);
528 BYTE* B = _save.Ref();
529 MemCopy(B, P1, l1);
530 B += l1;
531 MemCopy(B, P2, l2);
532 B += l2;
533 MemCopy(B, P3, l3);
534 B += l3;
535 _DeleteObject(hTmp);
536 return ERROR_SUCCESS;
537 }
538 #endif
539
549 static DWORD Save(LPCTSTR lpszFileName, HBITMAP bmp, WORD bitsPixel = 0)
550 {
551 CWorkMem m;
552 DWORD r = SaveMemory(m, bmp, bitsPixel);
553 if ( r != ERROR_SUCCESS )
554 {
555 return r;
556 }
557 // ファイル出力オープン
558 HANDLE hFile = ::CreateFile(lpszFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
559 if ( hFile == INVALID_HANDLE_VALUE )
560 {
561 return _GetLastError("CreateFile");
562 }
563 DWORD tmp;
564 if ( ! ::WriteFile(hFile, m.Ref(), ToDword(m.GetSize()), &tmp, NULL) )
565 {
566 DWORD r = _GetLastError("WriteFile");
567 ::CloseHandle(hFile);
568 return r;
569 }
570 ::CloseHandle(hFile);
571 return ERROR_SUCCESS;
572 }
573};
574
575
576
577};//TNB
ポインタハンドル関係のヘッダ
HBITMAP型ハンドルハンドル
CBitmapHandle(void)
コンストラクタ.
CBitmapHandle(const CString &strFile, int cx=0, int cy=0, UINT fuLoad=LR_CREATEDIBSECTION)
代入コンストラクタ.
bool GetSize(SIZE &_size) const
[取得] ビットマップサイズ取得.
static HBITMAP Load(LPCTSTR lpszFileName, int cx=0, int cy=0, UINT fuLoad=LR_CREATEDIBSECTION)
[読込] BMPファイル読込み.
CBitmapHandle(HBITMAP P)
代入コンストラクタ.
CBitmapHandle(UINT uBitmapResourceId, int cx=0, int cy=0, UINT fuLoad=LR_CREATEDIBSECTION)
代入コンストラクタ.
DWORD Save(LPCTSTR lpszFileName, WORD bitsPixel=0)
[作成] BMPファイル作成.
void SetClone(HBITMAP hBmp)
[設定] HBITMAPセット.
bool Draw(HDC hdc, int x=0, int y=0) const
[処理] イメージ描画.
CBitmapHandle(const CBitmapHandle &other)
コピーコンストラクタ.
static HBITMAP Load(UINT uBitmapResourceId, int cx=0, int cy=0, UINT fuLoad=LR_CREATEDIBSECTION)
[読込] リソース読込み
static DWORD SaveMemory(CWorkMem &_save, HBITMAP bmp, WORD bitsPixel=0)
[作成] BMPファイルイメージ作成.
static HBITMAP Create32bitDibSection(HBITMAP hbm, RGBQUAD *&_pRgb, BITMAPINFOHEADER *pHeader=NULL)
[作成] 32bitビットマップ作成.
static DWORD Save(LPCTSTR lpszFileName, HBITMAP bmp, WORD bitsPixel=0)
[作成] BMPファイル作成.
static HBITMAP LoadOem(UINT uOemBitmapResourceId, int cx=0, int cy=0, UINT fuLoad=0)
[読込] OEMリソース読込み
HBITMAP Detach(void)
[取得] デタッチ.
static bool Draw(HDC hdc, HBITMAP hBmp, int x=0, int y=0)
[処理] イメージ描画.
CBitmapHandle(LPCTSTR lpszFile, int cx=0, int cy=0, UINT fuLoad=LR_CREATEDIBSECTION)
代入コンストラクタ.
ポインタハンドルテンプレートベースクラス
CPointerHandleBaseT & operator=(HBITMAP t)
[代入] 代入.
size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbDef.h:665
void Resize(size_t l)
[設定] サイズ再設定
Definition: TnbDef.h:672
const TYP * Ref(void) const
[取得] ポインタ取得
Definition: TnbDef.h:712
DWORD ToDword(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:395
void Zero(V &value)
[設定] ゼロクリア.
Definition: TnbDef.h:399
HINSTANCE GetInstanceHandleByTnb(EInstanceType type=EI_Process)
[取得] インスタンスハンドル取得.
Definition: TnbDef.h:1341
@ EI_Bitmap
ビットマップリソース用
Definition: TnbDef.h:1260
TNB Library
Definition: TnbDoxyTitle.txt:2
void MemCopy(T *_pDst, const void *pSrc, size_t len)
[複製] メモリコピー
Definition: TnbDef.h:376