win32连接图片原理:
将图片1写入到一个 内存位置,将图片2写到另一个内存位置,然后新建一个新的足以容纳这2张图片的内存,分别将2个图片,依次拷贝到较大的新的内存位置.
先来看看代码:
/*----------------------------------------
BRICKS1.C -- LoadBitmap Demonstration
(c) Charles Petzold, 1998
----------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName [] = TEXT ("Bricks1") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
// wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.hbrBackground = NULL ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("LoadBitmap Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmap,hBitmap2,memBM ;
static int cxClient, cyClient, cxSource, cySource,cxSource2, cySource2 ;
BITMAP bitmap,bitmap2 ;
static HDC hdc, hdcMem = NULL,hdcMem2 ,hdcMem3;
static HINSTANCE hInstance ;
// HBITMAP memBM;
// Getwindows
static int x = -10, y = 0,x2 = 0,m_x = 0;
static int xfirst ;
static int xsecond;
PAINTSTRUCT ps ;
POINT MousePointFirst;
POINT MousePointSecond;
RECT ClientRect;
static BOOL sign = TRUE;
static BOOL Isfirst = TRUE;
switch (message)
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
hBitmap = LoadBitmap (hInstance, TEXT ("IDB_BITMAP5")) ;
hBitmap2 = LoadBitmap (hInstance,TEXT("IDB_BITMAP3"));
// hdcMem = CreateCompatibleDC (hdc) ;
//hdcMem2 = CreateCompatibleDC (hdc) ;
//hdcMem3 = CreateCompatibleDC (hdc) ;
//SelectObject(hdcMem,hBitmap);
//SelectObject(hdcMem2,hBitmap2);
// GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
//GetObject (hBitmap2, sizeof (BITMAP), &bitmap2) ;
// cxSource = bitmap.bmWidth ;
// cySource = bitmap.bmHeight ;
//cxSource2 = bitmap2.bmWidth ;
//cySource2 = bitmap2.bmHeight ;
//memBM = CreateCompatibleBitmap(hdc,cxSource*2,cySource);
//SelectObject(hdcMem3,memBM);
//BitBlt(hdcMem3,0,0,cxSource,cySource,hdcMem,0,0,SRCCOPY);
//DeleteDC(hdcMem);
//BitBlt(hdcMem3,cxSource,0,cxSource2,cySource2,hdcMem2,0,0,SRCCOPY);
//DeleteDC(hdcMem2);
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
// x2 = 0;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
if(sign == TRUE)
{
hdcMem = CreateCompatibleDC (hdc) ;
hdcMem2 = CreateCompatibleDC (hdc) ;
hdcMem3 = CreateCompatibleDC (hdc) ;
SelectObject(hdcMem,hBitmap);
SelectObject(hdcMem2,hBitmap2);
GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
GetObject (hBitmap2, sizeof (BITMAP), &bitmap2) ;
cxSource = bitmap.bmWidth ;
cySource = bitmap.bmHeight ;
cxSource2 = bitmap2.bmWidth ;
cySource2 = bitmap2.bmHeight ;
memBM = CreateCompatibleBitmap(hdc,cxSource+cxSource2,cySource);
SelectObject(hdcMem3,memBM);
BitBlt(hdcMem3,0,0,cxSource,cySource,hdcMem,0,0,SRCCOPY);
DeleteDC(hdcMem);
BitBlt(hdcMem3,cxSource,0,cxSource2,cySource2,hdcMem2,0,0,SRCCOPY);
DeleteDC(hdcMem2);
BitBlt(hdc,0,0,cxSource+cxSource2,cySource,hdcMem3,cxSource,0,SRCCOPY);
}
else
{
m_x += 100;
hdcMem = CreateCompatibleDC (hdc) ;
hdcMem2 = CreateCompatibleDC (hdc) ;
hdcMem3 = CreateCompatibleDC (hdc) ;
SelectObject(hdcMem,hBitmap);
SelectObject(hdcMem2,hBitmap2);
GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
GetObject (hBitmap2, sizeof (BITMAP), &bitmap2) ;
cxSource = bitmap.bmWidth ;
cySource = bitmap.bmHeight ;
cxSource2 = bitmap2.bmWidth ;
cySource2 = bitmap2.bmHeight ;
memBM = CreateCompatibleBitmap(hdc,cxSource+cxSource2,cySource);
SelectObject(hdcMem3,memBM);
BitBlt(hdcMem3,0,0,cxSource,cySource,hdcMem,0,0,SRCCOPY);
DeleteDC(hdcMem);
BitBlt(hdcMem3,cxSource,0,cxSource2,cySource2,hdcMem2,0,0,SRCCOPY);
DeleteDC(hdcMem2);
if(x >= cxSource )
{
BitBlt(hdc,0,0,cxSource+cxSource2,cySource,hdcMem3,cxSource,0,SRCCOPY);
}
else
{
BitBlt(hdc,0,0,cxSource+cxSource2,cySource,hdcMem3,m_x,0,SRCCOPY);
}
}
DeleteDC (hdcMem3) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_MOUSEMOVE:
if(wParam & MK_LBUTTON)
{
sign = FALSE;
//GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
//cxSource = bitmap.bmWidth ;
//cySource = bitmap.bmHeight ;
if(Isfirst == TRUE)
{
x = 0;
Isfirst = FALSE;
}
else
{
xfirst = xsecond;
GetCursorPos(&MousePointSecond);
xsecond = MousePointSecond.x;
x=xsecond - xfirst;
}
InvalidateRect(hwnd,NULL,TRUE);
}
return 0;
case WM_LBUTTONUP:
sign = FALSE;
//if(x2 > 500)
//{
// x = x2 = 0;
// SelectObject (hdcMem, hBitmap2) ;
// // BitBlt (hdc, 0, 0, cxSource, cySource, hdcMem, 0, 0, SRCCOPY) ;
//}
//else
//{
// x = x2 = 0;
// SelectObject (hdcMem, hBitmap);
//}
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_DESTROY:
DeleteObject (hBitmap) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
图片连接的实现,主要是 WM_PAINT里的代码,我们具体来分析一下:
(1)创建一个与指定设备兼容的内存设备上下文环境(DC)
hdcMem = CreateCompatibleDC (hdc) ;
hdcMem2 = CreateCompatibleDC (hdc) ;
hdcMem3 = CreateCompatibleDC (hdc) ;
(2)将hdcMem,hdcMem2,分别关联要进行连接的图片
SelectObject(hdcMem,hBitmap);
SelectObject(hdcMem2,hBitmap2);
(3)创建一个内存兼容图片,图片的大小应该是2张图片的2倍(看水平,还是垂直),并将兼容图片和hdcMem3关联
memBM = CreateCompatibleBitmap(hdc,cxSource+cxSource2,cySource);
SelectObject(hdcMem3,memBM);
(4)将hdcMem1 hdcMem2,依次拷贝到hdcMem3中,注意,第二次的起始位置,应该是第一次图片的长度
BitBlt(hdcMem3,0,0,cxSource,cySource,hdcMem,0,0,SRCCOPY);
DeleteDC(hdcMem);
BitBlt(hdcMem3,cxSource,0,cxSource2,cySource2,hdcMem2,0,0,SRCCOPY);
DeleteDC(hdcMem2);
(5)最后将hdcMem3写到窗口的dc,便可以显示出来了哦
BitBlt(hdc,0,0,cxSource+cxSource2,cySource,hdcMem3,0,0,SRCCOPY);