/* * smooth.cpp */ /* *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* Comment: ビットマップをスムーズにドラッグ Author: 火星の砂塊 E-Mail: unq@capella.freemail.ne.jp HP : http://hp.vector.co.jp/authors/VA023539/ *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* */ #include #include #include "diblib\diblib.h" #include "resource.h" const char szClassName[]="smooth"; HMODULE hAppModule= NULL; POINT dibpos = {10,10}; POINT offset; diblib::CDIBitmap dib; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); __inline void GetDIBRect(LPRECT in_pRect) { SIZE s; dib.GetBitmapSize(&s); ::SetRect(in_pRect,dibpos.x,dibpos.y, dibpos.x+s.cx,dibpos.y+s.cy); } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { hAppModule=(HMODULE)hInstance; WNDCLASSEX wc; wc.cbClsExtra = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.cbWndExtra = 0; wc.hbrBackground= (HBRUSH)(COLOR_WINDOW+1); wc.hCursor = ::LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW)); wc.hIcon = ::LoadIcon(hAppModule,MAKEINTRESOURCE(IDI_ICON1)); wc.hIconSm = NULL; wc.hInstance = hInstance; wc.lpfnWndProc = (WNDPROC)WndProc; wc.lpszClassName= szClassName; wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW; ::RegisterClassEx(&wc); HWND hWnd=::CreateWindow(szClassName,szClassName, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT, 200,200,NULL,NULL,hInstance,0); if ( hWnd==NULL ) return 0; ::ShowWindow(hWnd,nCmdShow); MSG msg; while ( ::GetMessage(&msg,NULL,0,0) ) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WndProc(HWND in_hWnd, UINT in_Message, WPARAM in_wParam, LPARAM in_lParam) { HDC hDC=NULL; POINT pt; RECT rct; switch ( in_Message ) { case WM_CREATE: hDC=::CreateCompatibleDC(NULL); dib.Create(hDC,IDB_BITMAP1,hAppModule); ::DeleteDC(hDC); break; case WM_PAINT: PAINTSTRUCT ps; hDC=::BeginPaint(in_hWnd,&ps); dib.BitBlt(hDC,dibpos.x,dibpos.y,SRCCOPY); ::EndPaint(in_hWnd,&ps); break; case WM_LBUTTONDOWN: pt.x= GET_X_LPARAM(in_lParam); pt.y= GET_Y_LPARAM(in_lParam); GetDIBRect(&rct); if ( ::PtInRect(&rct,pt) ) { ::SetCapture(in_hWnd); offset.x= pt.x-dibpos.x; offset.y= pt.y-dibpos.y; } break; case WM_MOUSEMOVE: if ( ::GetCapture()!=in_hWnd ) return 0; HRGN hRgn1,hRgn2,hRgn3; // 移動前の位置を取得 GetDIBRect(&rct); hRgn1= ::CreateRectRgnIndirect(&rct); // 移動後の新しいビットマップ位置を代入 pt.x= GET_X_LPARAM(in_lParam); pt.y= GET_Y_LPARAM(in_lParam); dibpos.x= pt.x-offset.x; dibpos.y= pt.y-offset.y; // 移動後の位置を取得 GetDIBRect(&rct); hRgn2= ::CreateRectRgnIndirect(&rct); // 関数に渡す前に初期化が必要 hRgn3= ::CreateRectRgnIndirect(&rct); // リージョンの引き算 ::CombineRgn(hRgn3,hRgn1,hRgn2,RGN_DIFF); hDC=::GetDC(in_hWnd); dib.BitBlt(hDC,dibpos.x,dibpos.y,SRCCOPY); ::ReleaseDC(in_hWnd,hDC); ::InvalidateRgn(in_hWnd,hRgn3,TRUE); ::UpdateWindow(in_hWnd); ::DeleteObject(hRgn1); ::DeleteObject(hRgn2); ::DeleteObject(hRgn3); break; case WM_LBUTTONUP: ::ReleaseCapture(); break; case WM_DESTROY: ::PostQuitMessage(0); break; default: return ::DefWindowProc(in_hWnd, in_Message,in_wParam,in_lParam); } return 0; }