ActiveX для получения подписи
От: noonv Россия http://www.robocraft.ru
Дата: 31.08.05 09:53
Оценка:
Пишу 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 (что может вытекать из первого) .
Хотелось бы услышать ваши соображения
Всем заранее — спасибо.
http://robocraft.ru
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.