Пишу ActiveX для получения подписи
, использую ATL. В ActiveX Control Test Container-е всё работает, а при использовании объекта в IE иногда вместо подписи сохраняется просто тёмно-серый прямоугольник
— так же странно ведёт себя Release -версия объекта — подпись рисуется на том-же тёмно-сером фоне
// CGetSignature
LRESULT CGetSignature::OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HPEN pen,oldpen;
int xPos = (short)LOWORD(lParam);
int yPos = (short)HIWORD(lParam);
thisdc=this->GetDC();
HDC hdc;
if(m_hWnd!=NULL)
{
hdc=::GetDC(m_hWnd);
}
else
{
HWND hWnd;
m_spInPlaceSite->GetWindow(&hWnd);
hdc=::GetDC(hWnd);
}
thisdc=hdc;
GetClientRect(rect);
iWidth=rect->right-rect->left;
iHeight=rect->bottom-rect->top;
if (!memdc)
{
memdc=CreateCompatibleDC(thisdc);
if(memdc)
{
SetBkColor(memdc, RGB(255,255,255));
ExtTextOut(memdc, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
}
SetBkColor(thisdc, RGB(255,255,255));
ExtTextOut(thisdc, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
}
else
{
StretchBlt( thisdc, 0, 0, rect->right-rect->left,rect->bottom-rect->top,
memdc, 0, 0, rect->right-rect->left,rect->bottom-rect->top,SRCCOPY);
}
if (!memdc)
{
ATLTRACE(_T("Error create memdc\n"));
return 2;
}
pen= CreatePen(PS_SOLID,pen_width,RGB(0,0,0));
if (wParam & MK_LBUTTON)
{
if(!m_xPos && !m_yPos)
{
m_xPos=xPos;
m_yPos=yPos;
}
oldpen=(HPEN)SelectObject(thisdc,pen);
MoveToEx(thisdc,m_xPos,m_yPos,(LPPOINT) NULL);
LineTo(thisdc,xPos,yPos);
SelectObject(thisdc,oldpen);
DeleteObject(pen);
m_xPos = xPos;
m_yPos = yPos;
}
// StretchBlt( memdc, 0, 0, rect->right-rect->left,rect->bottom-rect->top,
// thisdc, 0, 0, rect->right-rect->left,rect->bottom-rect->top,SRCCOPY);
this->ReleaseDC(thisdc);
bHandled=true;
return 0;
}
LRESULT CGetSignature::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
if(memdc)
DeleteDC(memdc);
bHandled=true;
if(rect)
delete rect;
return 0;
}
LRESULT CGetSignature::OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
m_xPos=0;
m_yPos=0;
bHandled=true;
return 0;
}
STDMETHODIMP CGetSignature::get_pen_width(int* pVal)
{
// TODO: Add your implementation code here
*pVal=pen_width;
return S_OK;
}
STDMETHODIMP CGetSignature::put_pen_width(int newVal)
{
// TODO: Add your implementation code here
if(newVal<=0)
newVal=2;
pen_width=newVal;
return S_OK;
}
void CGetSignature::SaveBitmap()
{
//
// save HDC into bitmap
//
//
// 1. save HDC into HBITMAP
//
HBITMAP oldbitmap;
thisdc=this->GetDC();
HDC memdc2=CreateCompatibleDC(thisdc);
hBitmap=CreateCompatibleBitmap(thisdc,iWidth,iHeight);
if(!hBitmap)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,0,NULL);
MessageBox("Error hBitmap", "Error", MB_OK | MB_ICONINFORMATION);
MessageBox((LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
LocalFree(lpMsgBuf);
}
if (!memdc2)//metadc)
{
MessageBox("Error memdc2", "Error", MB_OK | MB_ICONINFORMATION);
ATLTRACE(_T("Error create memdc2\n"));
return;
}
oldbitmap = (HBITMAP)SelectObject(memdc2, hBitmap);
StretchBlt( memdc2, 0, 0, rect->right-rect->left,rect->bottom-rect->top,
thisdc, 0, 0, rect->right-rect->left,rect->bottom-rect->top,SRCCOPY);
/// SelectObject(memdc2, oldbitmap);
if(memdc2)
DeleteDC(memdc2);
//
// 2. save HBITMAP into .bmp
//
//
// save bitamp from HDC
//
// http://www.rsdn.ru/Forum/Message.aspx?mid=354271#354271
//
if (NULL != hBitmap)
{
//Here stores the bitmap to the file
// ...
//Gets bitmap size
BITMAP csBitmapSize;
// Get bitmap size
int nRetValue = GetObject(hBitmap, sizeof(csBitmapSize), &csBitmapSize);
if (nRetValue)
{
DWORD dwWidth = (DWORD)csBitmapSize.bmWidth -2; //##
DWORD dwHeight = (DWORD)csBitmapSize.bmHeight -4; //##
HDC hDC = thisdc;
HDC hSrcDC = CreateCompatibleDC(hDC);
HDC hDestDC = CreateCompatibleDC(hDC);
if(!hSrcDC)
MessageBox("Error hSrcDC", "Error", MB_OK | MB_ICONINFORMATION);
if(!hDestDC)
MessageBox("Error hDestDC", "Error", MB_OK | MB_ICONINFORMATION);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hSrcDC, hBitmap);
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 8; //32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;
COLORREF* pSrcBits = NULL;
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits,
NULL, NULL);
HBITMAP hOldDestBmp = (HBITMAP)SelectObject(hDestDC, hSrcDib);
BitBlt(hDestDC, 0, 0, dwWidth, dwHeight, hSrcDC, 0, 0, SRCCOPY);
SelectObject(hDestDC, hOldDestBmp);
DeleteObject(hOldDestBmp);
DeleteDC(hDestDC);
SelectObject(hSrcDC, hOldBitmap);
DeleteObject(hOldBitmap);
DeleteDC(hSrcDC);
ReleaseDC(hDC);
//
// write to file
//
HANDLE hFile;
unsigned long int iwrited;
char* filename="C:\\signature.bmp";
DeleteFile(filename);
hFile = CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
if (hFile == NULL || hFile == INVALID_HANDLE_VALUE)
{
ATLTRACE(_T("Error CreateFile()\n"));
return;
}
BITMAPFILEHEADER bfh;
memset(&bfh, 0, sizeof (BITMAPFILEHEADER));
bfh.bfType = 'MB';
bfh.bfSize = sizeof(bfh) + dwWidth * dwHeight * 1/*4*/ + sizeof( BITMAPINFOHEADER );
bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
WriteFile(hFile,&bfh,sizeof(bfh),&iwrited,NULL);
WriteFile(hFile,lpbiSrc,sizeof(*lpbiSrc),&iwrited,NULL);
WriteFile(hFile,(BYTE*)pSrcBits,dwWidth * dwHeight * 1/*4*/,&iwrited,NULL);
FlushFileBuffers(hFile);
DeleteObject(hSrcDib);
delete [] lpbiSrc;
} //if
} //if
ReleaseDC(thisdc);
}
LRESULT CGetSignature::OnRButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
SaveBitmap();
bHandled=true;
return 0;
}
STDMETHODIMP CGetSignature::SavePicture(void)
{
SaveBitmap();
return S_OK;
}
STDMETHODIMP CGetSignature::ClearPicture(void)
{
if(rect)
{
thisdc=::GetDC(m_hWnd);
if(thisdc)
{
SetBkColor(thisdc, RGB(255,255,255));
ExtTextOut(thisdc, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
}
}
return S_OK;
}
косяк может быть, как в получении HDC, так и в получении HBITMAP (что может вытекать из первого)
.
Хотелось бы услышать ваши соображения
Всем заранее — спасибо.