Pada artikel ini, saya ingin sedikit berbagi cara meletakkan gambar pada latar belakang form MDI. Sebenarnya secara pemrograman tidak sulit. hanya saja pemrograman seperti dibawah ini jarang disentuh programmer-programer pemula. Gambar yang ingin saya pakai adalah BMP dan saya akan menggambarkan pada seluruh layar (stretch). Silakan modifikasi program saya ini untuk tipe gambar yang lain.
Inti dari pemrograman gambar background adalah menggambar dengan fungsi Windows. Fungsi WIndows yang asli tidak mengerjakan penggambaran background, sehingga kita harus menggantikannya dengan prosedur buatan kita sendiri. Fungsi yang akan kita ubah isinya tadi adalah CreateWnd.
Pada saat menggambar Window dengan CreateWnd, program akan memanggil fungsi GambarPenuh buatan kita. Fungsi GambarPenuh akan mendapatkan gambar dari VCL TImage bernama img.
procedure TFormUtama.GambarPenuh;
var
WilayahGambar : TRect;
begin
GetWindowRect(ClientHandle, WilayahGambar);
StretchBlt(FDrawDC, 0, 0, WilayahGambar.Right, WilayahGambar.Bottom,
imgUtama.Picture.Bitmap.Canvas.Handle, 0, 0,
imgUtama.Picture.Width, imgUtama.Picture.Height, SRCCOPY);
end;
Wilayah gambar mendefinisikan titik pada bidang yang kita gambar. Dalam contoh ini berarti wilayah pada form MDI Parent. Kita memberitahu wilayah gambar tersebut dengan perintah GetWindowRect milik unit Windows.
Struktur GetWindowsRect sendiri dalam C++ adalah
BOOL WINAPI GetWindowRect(
_In_ HWND hWnd,
_Out_ LPRECT lpRect
);
dengan
HWND | handle windows |
LPRECT | pointer untuk struktur REC (di Delphi pada class TREC) yang menerima koordinat form dari kiri atas dan kanan bawah |
Sesudah mendapatkan contekan gambar, gambar tersebut akan diletakkan di memori terlebih dahulu sebelum diletakkan di tujuan dalam wujud persegi penuh (stretch) dengan prosedur StretchBlt.
Struktur StretchBlt pada C++
BOOL StretchBlt(
_In_ HDC hdcDest,
_In_ int nXOriginDest,
_In_ int nYOriginDest,
_In_ int nWidthDest,
_In_ int nHeightDest,
_In_ HDC hdcSrc,
_In_ int nXOriginSrc,
_In_ int nYOriginSrc,
_In_ int nWidthSrc,
_In_ int nHeightSrc,
_In_ DWORD dwRop
);
Keterangan:
hdcDest | handle form tujuan |
nXOriginDest | Koordinat x, satuan logical units, kiri-atas tujuan dalam bentuk persegi |
nYOriginDest | Koordinat y, satuan logical units, kiri atas tujuan dalam bentuk persegi |
nWidthDest | lebar form tujuan dalam persegi |
nHeightDest | Tinggi form tujuan dalam bentuk persegi |
hdcSrc | Handle untuk sumber |
nXOriginSrc | Koordinat x, satuan logical units, kiri-atas sumber dalam persegi |
nWidthSrc | Lebar sumber, satuan logical units dalam persegi |
nYOriginSrc | Koordinat y, satuan logical units, kiri atas sumber dalam persegi |
nHeightSrc | Tinggi sumber, satuan logical units, dalam persegi |
dwRop | Pilihan operasi raster |
Jangan dijalankan terlebih dahulu. Pekerjaan kita masih belum lengkap. Kita masih harus menumpuk fungsi penggambaran windows dengan prosedur milik kita sendiri.
protected
procedure CreateWnd; override;
Kita tidak perlu capek-capek membuat segala fungsi dari awal. Sehingga fungsi induk kita turunkan langsung dengan:
inherited CreateWnd;
Definisikan variabel yang akan kita pakai pada bagian private:
private
FProsedurLama,
FProsedurBaru: TFarProc;
FDrawDC: hDC;
dan kita tulis prosedurnya:
procedure TFormUtama.CreateWnd;
begin
inherited CreateWnd;
//Berikan ClientWndProc sebagai prosedur Window
FProsedurBaru := MakeObjectInstance(ClientWndProc);
//Ambil pointer dari prosedur default
FProsedurLama := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
//Beritahu agar prosedur buatan kita menjadi default prosedur Window
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FProsedurBaru));
end;
sedangkan prosedur penggambaran windowsnya adalah sebagai berikut:
procedure TFormUtama.ClientWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_ERASEBKGND:
begin
CallWindowProc(FProsedurLama, ClientHandle, Message.Msg, Message.wParam,
Message.lParam);
FDrawDC := TWMEraseBkGnd(Message).DC;
GambarPenuh;
Message.Result := 1;
end;
WM_VSCROLL, WM_HSCROLL:
begin
Message.Result := CallWindowProc(FProsedurLama, ClientHandle, Message.Msg,
Message.wParam, Message.lParam);
InvalidateRect(ClientHandle, nil, True);
end;
else
Message.Result := CallWindowProc(FProsedurLama, ClientHandle, Message.Msg,
Message.wParam, Message.lParam);
end;
end;
Kode program selengkapnya
0 comments:
Posting Komentar