動作環境
C++ Builder XE4
[bcc32 エラー] Unit1.cpp(50): E2034 'HBITMAP__ *' 型は 'HDC__ *' 型に変換できない
詳細な解析情報
Unit1.cpp(23): 構文解析対象: void _fastcall TForm1::Button1Click(TObject *)
[bcc32 エラー] Unit1.cpp(50): E2342 パラメータ 'hdc' は HDC__ * 型として定義されているので HBITMAP__ * は渡せない
詳細な解析情報
Unit1.cpp(23): 構文解析対象: void _fastcall TForm1::Button1Click(TObject *)
問題のコード
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <pngimage.hpp>
#include <ClipBrd.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
static const int kNum_div = 6; // 画像分割数 (水平と垂直で同じ分割). 3:任意
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 0. オリジナルの位置を保持
int preTop = Chart1->Top;
int preLeft = Chart1->Left;
// 1. 部分ごとにキャプチャして連結する
int clipWidth = Panel1->Width / kNum_div; // 切取り高さ
int clipHeight = Panel1->Height / kNum_div; // 切取り幅
TBitmap *bmp_whole = new TBitmap(); // A. 全画像を載せる
TBitmap *bmp_frac = new TBitmap(); // B. 部分ごとにキャプチャし、逐次Aに載せる
bmp_frac->SetSize(clipWidth, clipHeight);
bmp_whole->SetSize( Panel1->Width, Panel1->Height );
HDC dc_frac = GetDC(Panel1->Handle); // BitBit()用
for(int ri = 0; ri < kNum_div; ri++) { // ri: row index
for(int ci = 0; ci < kNum_div; ci++) { // ci: column index
// Panel上でキャプチャ対象部分をキャプチャ位置に移動 (左上でキャプチャする)
Chart1->Top = -(ri * clipHeight);
Chart1->Left = -(ci * clipWidth);
// 下記のwaitがないと画像取得に失敗し、[左上の画像 * N個]になる
Sleep(10); // msec
Application->ProcessMessages();
// 常に左上の位置(0,0)でキャプチャする
::BitBlt(bmp_frac->Handle, 0, 0, clipWidth, clipHeight, dc_frac, 0, 0, SRCCOPY);
// キャプチャしたものを逐次、全画像用BMPに描く
bmp_whole->Canvas->Draw(clipWidth * ci, clipHeight * ri, bmp_frac);
}
}
Image1->Picture->Assign(bmp_whole);
// 2. Chart1を元の位置に戻す
Chart1->Top = preTop;
Chart1->Left = preLeft;
// 3. クリップボードへ
Clipboard()->Assign(bmp_whole);
// 4, 手仕舞い
delete bmp_whole;
delete bmp_frac;
// 5. ペイントブラシ起動 (ctrl + vでの動作確認用)
ShellExecute(NULL, NULL, L"pbrush.exe", L"", NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
// Chart1はPanel1上に配置されている
// 上下左右をPanel1に合わせて伸縮するようにする
Chart1->Anchors = TAnchors() << akLeft << akTop << akRight << akBottom;
// デザイン画面で重なりを明白にするため、サイズを変えていたが、
// 本来はChart1とPanel1は同じサイズとする
Chart1->Top = 0;
Chart1->Left = 0;
Chart1->Height = Panel1->Height;
Chart1->Width = Panel1->Width;
// Panelのサイズを拡大 (画面に入りきらないサイズの例として)
Panel1->Height *= 2;
}
//---------------------------------------------------------------------------
問題の箇所
// 常に左上の位置(0,0)でキャプチャする
::BitBlt(bmp_frac->Handle, 0, 0, clipWidth, clipHeight, dc_frac, 0, 0, SRCCOPY);
正しい実装
// 常に左上の位置(0,0)でキャプチャする
::BitBlt(bmp_frac->Canvas->Handle, 0, 0, clipWidth, clipHeight, dc_frac, 0, 0, SRCCOPY);
bmp_fracの「Canvasの」Handleを使う。