送分!!求对图片实现拖动显示(用MOUSE)和缩放,旋转的源代码或方法.多谢!!! 谢各位帮帮忙啦.我一定重谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 拖动的图片,参考:http://www.codeguru.com/Cpp/controls/listview/dragdrop/article.php/c6399/ 缩放: HDIB ChangeDIBSize(HDIB hDIB, int nWidth, int nHeight){ LPBITMAPINFO lpbmi = NULL; LPBYTE lpSourceBits, lpTargetBits, lpResult; HDC hDC = NULL, hSourceDC, hTargetDC; HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap; DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize; HDIB hNewDIB; DWORD dwSize; WaitCursorBegin(); // Get DIB pointer if (! hDIB) { WaitCursorEnd(); return NULL; } LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB); if (! lpSrcDIB) { WaitCursorEnd(); return NULL; } // Allocate and fill out a BITMAPINFO struct for the new DIB dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) + PaletteSize(lpSrcDIB); lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize ); memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize); lpbmi->bmiHeader.biWidth = nWidth; lpbmi->bmiHeader.biHeight = nHeight; // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em hDC = GetDC( NULL ); hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 ); hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 ); hSourceDC = CreateCompatibleDC( hDC ); hTargetDC = CreateCompatibleDC( hDC ); // Flip the bits on the source DIBSection to match the source DIB dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader)); dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpbmi->bmiHeader)); memcpy( lpSourceBits, FindDIBBits((LPBYTE)lpSrcDIB), dwSourceBitsSize ); lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize; // Select DIBSections into DCs hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap ); hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap ); // put old bitmap in new bitmap SetStretchBltMode( hTargetDC, COLORONCOLOR ); StretchBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight, SRCCOPY ); // Clean up and delete the DCs SelectObject( hSourceDC, hOldSourceBitmap ); SelectObject( hTargetDC, hOldTargetBitmap ); DeleteDC( hSourceDC ); DeleteDC( hTargetDC ); ReleaseDC( NULL, hDC ); // Flush the GDI batch, so we can play with the bits GdiFlush(); // Allocate enough memory for the new CF_DIB, and copy bits dwSize = dwTargetHeaderSize + dwTargetBitsSize; hNewDIB = GlobalAlloc(GHND, dwSize); lpResult = (LPBYTE)GlobalLock(hNewDIB);//malloc( dwTargetHeaderSize + dwTargetBitsSize ); memcpy( lpResult, lpbmi, dwTargetHeaderSize ); memcpy( FindDIBBits( (LPBYTE)lpResult ), lpTargetBits, dwTargetBitsSize ); // final cleanup DeleteObject( hTargetBitmap ); DeleteObject( hSourceBitmap ); free( lpbmi ); GlobalUnlock(hDIB); GlobalUnlock(hNewDIB); WaitCursorEnd(); return hNewDIB;}旋转: HDIB RotateDIB(HDIB hDib){ WaitCursorBegin(); // old DIB LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib); DWORD lSrcWidth = DIBWidth(lpDIBSrc); DWORD lSrcHeight = DIBHeight(lpDIBSrc); WORD wBitCount = ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount; // bits position LPBYTE lpOldBits = FindDIBBits(lpDIBSrc); // get bytes/pixel, bytes/row of new DIB double fColorBytes = (double)((double)wBitCount/8.0); DWORD lSrcRowBytes = WIDTHBYTES(lSrcWidth*((DWORD)wBitCount)); DWORD lDestRowBytes = WIDTHBYTES(lSrcHeight*((DWORD)wBitCount)); // adjust new DIB size DWORD dwDataLength = GlobalSize(hDib); dwDataLength += lDestRowBytes*(lSrcWidth-1)+(DWORD)((lSrcHeight-1)*fColorBytes) - lSrcRowBytes*(lSrcHeight-1)+(DWORD)((lSrcWidth-1)*fColorBytes); HDIB hNewDib = GlobalAlloc(GHND, dwDataLength); if (! hNewDib) { WaitCursorEnd(); return NULL; } // new DIB buffer LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); // copy LPBITMAPINFO from old to new memcpy(lpDIB, lpDIBSrc, sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc)); // swap width and height ((LPBITMAPINFOHEADER)lpDIB)->biHeight = lSrcWidth; ((LPBITMAPINFOHEADER)lpDIB)->biWidth = lSrcHeight; // new bits position LPBYTE lpData = FindDIBBits(lpDIB); // trandform bits DWORD i, j; switch (wBitCount) { case 1: for (i=0; i<lSrcHeight; ++i) { for (j=0; j<lSrcWidth; ++j) { *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/8)) &= ~(1<<(7-((lSrcHeight-i-1)%8))); *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/8)) |= ((*(lpOldBits+(lSrcRowBytes*i+j/8))<<(j%8))>>7)<<(7-((lSrcHeight-i-1)%8)); } } break; case 4: for (i=0; i<lSrcHeight; ++i) { for (j=0; j<lSrcWidth; ++j) { *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/2)) &= ((lSrcHeight-i-1)%2) ? 0xf0 : 0x0f; *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/2)) |= ((*(lpOldBits+(lSrcRowBytes*i+j/2))<<(j%2 ? 4 : 0))>>4)<<(((lSrcHeight-i-1)%2) ? 0 : 4); } } break; case 8: for (i=0; i<lSrcHeight; ++i) { for (j=0; j<lSrcWidth; ++j) { *(lpData+(lDestRowBytes*j+lSrcHeight-i-1)) = *(lpOldBits+(lSrcRowBytes*i+j)); } } break; case 24: for (i=0; i<lSrcHeight; ++i) { for (j=0; j<lSrcWidth; j++) { *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)) = *(lpOldBits+(lSrcRowBytes*i+j*3)); *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)+1) = *(lpOldBits+(lSrcRowBytes*i+j*3)+1); *(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)+2) = *(lpOldBits+(lSrcRowBytes*i+j*3)+2); } } break; } // cleanup GlobalUnlock(hDib); GlobalUnlock(hNewDib); WaitCursorEnd(); return hNewDib;} drag:CPoint ptDrag;void CxxView::OnMouseMove(UINT nFlags, CPoint point) { CPoint pt; if (nFlags & MK_LBUTTON) { pt = GetScrollPosition() + ptDrag - point; ScrollToPosition(pt); ptDrag = point; }}void CxxView::OnLButtonDown(UINT nFlags, CPoint point) { ptDrag = point;} 呵呵!我也写过, 用到CRectTracker代码是不能给你的, 是公司的商业秘密 ! 我做过一个。不过,方法可能不是你想要用的。我用的是DIB的方法。每次缩放都生成一个新的图片。这样便于我处理。但是可能不是你想要的。还有左键框选区域。然后copy到剪切板。没有旋转。。加入就可以了。并不难。 http://www.codeguru.com/Cpp/W-D/doc_view/scrolling/article.php/c6101/我想有用,感谢vcleaner(我没做大哥已经很久了.......) ,我关注你很久了,你是个热心的人[email protected] win32 如何用鼠标控制图片的移动呢!! hellowin 里的一个return问题 CSDN 板主不能骂啊, 否则会出人命 窗体和可视化控件的继承问题 如何在组件中向客户程序发送一个windows消息 问个有关编译的问题 问一下,学过C++的学VC,应该先学WIN32 API还是MFC呢?!?! CListCtrl要设置成选中时为多列选中,而不是光第一列被选中,怎么搞? 提供车牌识别模块 MFC"打开"菜单的问题?? 我报 error LNK2001错啦!高手帮忙啦! (急)自己做的win界面版filedisk已能创建出盘符,但是无法访问
http://www.codeguru.com/Cpp/controls/listview/dragdrop/article.php/c6399/
HDIB ChangeDIBSize(HDIB hDIB, int nWidth, int nHeight)
{
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize;
HDIB hNewDIB;
DWORD dwSize; WaitCursorBegin(); // Get DIB pointer
if (! hDIB)
{
WaitCursorEnd();
return NULL;
}
LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDIB);
if (! lpSrcDIB)
{
WaitCursorEnd();
return NULL;
} // Allocate and fill out a BITMAPINFO struct for the new DIB
dwTargetHeaderSize = sizeof( BITMAPINFOHEADER ) + PaletteSize(lpSrcDIB);
lpbmi = (LPBITMAPINFO)malloc( dwTargetHeaderSize );
memcpy(lpbmi, lpSrcDIB, dwTargetHeaderSize);
lpbmi->bmiHeader.biWidth = nWidth;
lpbmi->bmiHeader.biHeight = nHeight;
// Gonna use DIBSections and BitBlt() to do the conversion, so make 'em
hDC = GetDC( NULL );
hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, (VOID **)&lpTargetBits, NULL, 0 );
hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, (VOID **)&lpSourceBits, NULL, 0 );
hSourceDC = CreateCompatibleDC( hDC );
hTargetDC = CreateCompatibleDC( hDC );
// Flip the bits on the source DIBSection to match the source DIB
dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
memcpy( lpSourceBits, FindDIBBits((LPBYTE)lpSrcDIB), dwSourceBitsSize );
lpbmi->bmiHeader.biSizeImage = dwTargetBitsSize;
// Select DIBSections into DCs
hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap );
hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap );
// put old bitmap in new bitmap
SetStretchBltMode( hTargetDC, COLORONCOLOR );
StretchBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight, SRCCOPY );
// Clean up and delete the DCs
SelectObject( hSourceDC, hOldSourceBitmap );
SelectObject( hTargetDC, hOldTargetBitmap );
DeleteDC( hSourceDC );
DeleteDC( hTargetDC );
ReleaseDC( NULL, hDC );
// Flush the GDI batch, so we can play with the bits
GdiFlush();
// Allocate enough memory for the new CF_DIB, and copy bits
dwSize = dwTargetHeaderSize + dwTargetBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize);
lpResult = (LPBYTE)GlobalLock(hNewDIB);//malloc( dwTargetHeaderSize + dwTargetBitsSize );
memcpy( lpResult, lpbmi, dwTargetHeaderSize );
memcpy( FindDIBBits( (LPBYTE)lpResult ), lpTargetBits, dwTargetBitsSize );
// final cleanup
DeleteObject( hTargetBitmap );
DeleteObject( hSourceBitmap );
free( lpbmi );
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
WaitCursorEnd();
return hNewDIB;
}
旋转:
HDIB RotateDIB(HDIB hDib)
{
WaitCursorBegin(); // old DIB
LPBYTE lpDIBSrc = (LPBYTE)GlobalLock(hDib); DWORD lSrcWidth = DIBWidth(lpDIBSrc);
DWORD lSrcHeight = DIBHeight(lpDIBSrc);
WORD wBitCount = ((LPBITMAPINFOHEADER)lpDIBSrc)->biBitCount;
// bits position
LPBYTE lpOldBits = FindDIBBits(lpDIBSrc); // get bytes/pixel, bytes/row of new DIB
double fColorBytes = (double)((double)wBitCount/8.0);
DWORD lSrcRowBytes = WIDTHBYTES(lSrcWidth*((DWORD)wBitCount));
DWORD lDestRowBytes = WIDTHBYTES(lSrcHeight*((DWORD)wBitCount)); // adjust new DIB size
DWORD dwDataLength = GlobalSize(hDib);
dwDataLength += lDestRowBytes*(lSrcWidth-1)+(DWORD)((lSrcHeight-1)*fColorBytes) -
lSrcRowBytes*(lSrcHeight-1)+(DWORD)((lSrcWidth-1)*fColorBytes);
HDIB hNewDib = GlobalAlloc(GHND, dwDataLength);
if (! hNewDib)
{
WaitCursorEnd();
return NULL;
}
// new DIB buffer
LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
// copy LPBITMAPINFO from old to new
memcpy(lpDIB, lpDIBSrc, sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIBSrc));
// swap width and height
((LPBITMAPINFOHEADER)lpDIB)->biHeight = lSrcWidth;
((LPBITMAPINFOHEADER)lpDIB)->biWidth = lSrcHeight;
// new bits position
LPBYTE lpData = FindDIBBits(lpDIB); // trandform bits
DWORD i, j;
switch (wBitCount)
{
case 1:
for (i=0; i<lSrcHeight; ++i)
{
for (j=0; j<lSrcWidth; ++j)
{
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/8)) &= ~(1<<(7-((lSrcHeight-i-1)%8)));
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/8)) |=
((*(lpOldBits+(lSrcRowBytes*i+j/8))<<(j%8))>>7)<<(7-((lSrcHeight-i-1)%8));
}
}
break;
case 4:
for (i=0; i<lSrcHeight; ++i)
{
for (j=0; j<lSrcWidth; ++j)
{
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/2)) &= ((lSrcHeight-i-1)%2) ? 0xf0 : 0x0f;
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)/2)) |=
((*(lpOldBits+(lSrcRowBytes*i+j/2))<<(j%2 ? 4 : 0))>>4)<<(((lSrcHeight-i-1)%2) ? 0 : 4);
}
}
break;
case 8:
for (i=0; i<lSrcHeight; ++i)
{
for (j=0; j<lSrcWidth; ++j)
{
*(lpData+(lDestRowBytes*j+lSrcHeight-i-1))
= *(lpOldBits+(lSrcRowBytes*i+j));
}
}
break;
case 24:
for (i=0; i<lSrcHeight; ++i)
{
for (j=0; j<lSrcWidth; j++)
{
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3))
= *(lpOldBits+(lSrcRowBytes*i+j*3));
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)+1)
= *(lpOldBits+(lSrcRowBytes*i+j*3)+1);
*(lpData+(lDestRowBytes*j+(lSrcHeight-i-1)*3)+2)
= *(lpOldBits+(lSrcRowBytes*i+j*3)+2);
}
}
break;
} // cleanup
GlobalUnlock(hDib);
GlobalUnlock(hNewDib);
WaitCursorEnd();
return hNewDib;
}
void CxxView::OnMouseMove(UINT nFlags, CPoint point)
{
CPoint pt; if (nFlags & MK_LBUTTON)
{
pt = GetScrollPosition() + ptDrag - point;
ScrollToPosition(pt);
ptDrag = point;
}
}void CxxView::OnLButtonDown(UINT nFlags, CPoint point)
{
ptDrag = point;
}
我也写过, 用到CRectTracker
代码是不能给你的, 是公司的商业秘密 !
我做过一个。
不过,方法可能不是你想要用的。
我用的是DIB的方法。
每次缩放都生成一个新的图片。这样便于我处理。但是可能不是你想要的。
还有左键框选区域。然后copy到剪切板。没有旋转。。加入就可以了。并不难。
我想有用,感谢vcleaner(我没做大哥已经很久了.......) ,我关注你很久了,你是个热心的人
[email protected]