Click here to Skip to main content
15,887,425 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
QuestionRe: CoCreateInstance fail for 64 bit Pin
Richard MacCutchan20-Feb-13 22:43
mveRichard MacCutchan20-Feb-13 22:43 
AnswerRe: CoCreateInstance fail for 64 bit Pin
john563220-Feb-13 23:32
john563220-Feb-13 23:32 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Richard MacCutchan20-Feb-13 23:58
mveRichard MacCutchan20-Feb-13 23:58 
GeneralRe: CoCreateInstance fail for 64 bit Pin
john563221-Feb-13 0:45
john563221-Feb-13 0:45 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Richard MacCutchan21-Feb-13 1:19
mveRichard MacCutchan21-Feb-13 1:19 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Jochen Arndt21-Feb-13 0:53
professionalJochen Arndt21-Feb-13 0:53 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Chris Losinger22-Feb-13 4:14
professionalChris Losinger22-Feb-13 4:14 
QuestionCursor from Bitmap Conundrum Pin
Ben Aldhouse20-Feb-13 21:36
Ben Aldhouse20-Feb-13 21:36 
Hello. I have a cursor conundrum. I am developing a custom control and one feature I want this custom control to have is the ability to be able to rearrange its appearance by dragging and dropping one part of it to another. The way I decided I would do this would be to:

1) Convert the selected area into a bitmap
2) Use the bitmap from 1) as the cursor until the drop point is selected.
3) Redraw the control in the new arrangement.

I am not worried about step 3). That should be trivial - it won't involve anything I haven't achieved already in my code concerning bitmaps or device contexts. However, I have a conundrum concerning step 2). I have achieved what I want to achieve but only if I save the bitmap to a file first then reload it as a cursor! What I am looking for here is a way of obtaining the bitmap data and converting it directly into a cursor. Clearly my problem stems from having cobbled together samples of code from various sources without properly understanding what is going on -

So I call the image capuring function on clicking the mouse...
C++
void CScrollBarEx::OnLButtonDown(UINT inFlags, CPoint inPoint) {
...
				CaptureAnImage(sliderVector[m_currentSlider-1].sliderRect);
...
}


and then you can see where I have edited out the code where I try and use the HBITMAP used to subsequently make a .bmp file to make the cursor - doing this always produces a black rectangle as the cursor. However- when I save that HBITMAP to .bmp file, then reload it into memory and use that to make a cursor - it works perfectly!

C++
int CScrollBarEx::CaptureAnImage(RECT sliderRect)
{
    //HDC hdcScreen;
    HDC hdcWindow;
    HDC hdcMemDC = NULL;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;

	HBITMAP m_hAndMask;
	HBITMAP m_hXorMask;


    // Retrieve the handle to a display device context for the client 
    // area of the window. 
    //hdcScreen =  (GetDC())->GetSafeHdc();
    hdcWindow = (GetDC())->GetSafeHdc();

    // Create a compatible DC which is used in a BitBlt from the window DC
    hdcMemDC = CreateCompatibleDC(hdcWindow); 


    if(!hdcMemDC)
    {
       // MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);
        goto done;
    }

    // Get the client area for size calculation
    RECT rcClient;
    GetClientRect(&rcClient);

    
	/*
	//This is the best stretch mode
    SetStretchBltMode(hdcWindow,HALFTONE);

    //The source DC is the entire screen and the destination DC is the current window (HWND)
    if(!StretchBlt(hdcWindow, 
               sliderRect.left ,sliderRect.top, 
               sliderRect.right, sliderRect.bottom, 
               hdcWindow, 
               0,0,
               GetSystemMetrics (SM_CXSCREEN),
               GetSystemMetrics (SM_CYSCREEN),
               SRCCOPY))
    {
        //MessageBox(hWnd, L"StretchBlt has failed",L"Failed", MB_OK);
        goto done;
    }
    */
	

    // Create a compatible bitmap from the Window DC
		//hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
	
	    //hbmScreen = CreateCompatibleBitmap(hdcWindow, sliderRect.right, sliderRect.bottom-sliderRect.top);
		
	    hbmScreen = CreateCompatibleBitmap(hdcWindow, sliderRect.right-sliderRect.left, sliderRect.bottom-sliderRect.top);

    
    if(!hbmScreen)
    {
        //MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK);
        goto done;
    }

	// Select the compatible bitmap into the compatible memory DC.
    SelectObject(hdcMemDC,hbmScreen);

    // Bit block transfer into our compatible memory DC.
    if(!BitBlt(hdcMemDC, 
               0,0,
               sliderRect.right-sliderRect.left, sliderRect.bottom-sliderRect.top, 
               hdcWindow, 
               sliderRect.left,sliderRect.top,
               SRCCOPY))
    {
        //MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK);
        goto done;
    }

	
	// Get the BITMAP from the HBITMAP
    GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);

	
    BITMAPFILEHEADER   bmfHeader;    
    BITMAPINFOHEADER   bi;
     
	
	bi.biSize = sizeof(BITMAPINFOHEADER);    
    bi.biWidth = bmpScreen.bmWidth;    
    bi.biHeight = bmpScreen.bmHeight;  
    bi.biPlanes = 1;    
    bi.biBitCount = 32;    
    bi.biCompression = BI_RGB;    
    bi.biSizeImage = 0;  
    bi.biXPelsPerMeter = 0;    
    bi.biYPelsPerMeter = 0;    
    bi.biClrUsed = 0;    
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

	// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
    // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
    // have greater overhead than HeapAlloc.
    HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); 
    char *lpbitmap = (char *)GlobalLock(hDIB);    
  
	// Gets the "bits" from the bitmap and copies them into a buffer 
    // which is pointed to by lpbitmap.
    GetDIBits(hdcWindow, hbmScreen, 0,
        (UINT)bmpScreen.bmHeight,
        lpbitmap,
        (BITMAPINFO *)&bi, DIB_RGB_COLORS);	

    // A file is created, this is where we will save the screen capture.
    HANDLE hFile = CreateFile(L"capture.bmp",
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, NULL);   
    
    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 
    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); 
    
    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB; 
    
    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM   
 
    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
    
    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);    
    GlobalFree(hDIB);


	//Close the handle for the file that was created
    CloseHandle(hFile);
	
	/*
	//20130216
	//Turn the cursor into a bitmap
	//HANDLE hNewBMP = CopyImage(hbmScreen,IMAGE_BITMAP,0,0,LR_COPYRETURNORG);
	m_hXorMask	  =  NULL;
	m_hAndMask	  =  NULL;
	//CColorCursor::GetMaskBitmaps(hbmScreen,RGB(0,0,0),m_hAndMask,m_hXorMask);
	m_hCursor = CColorCursor::CreateCursorFromBitmap(hbmScreen,RGB(0,0,0),0,0);
	//m_hCursor = CColorCursor::CreateCursorFromBitmap(hNewBMP,RGB(0,0,0),0,0);
	*/


	/*
	//Use Jiju George's bitmap drawing function
	HBITMAP aBMP = GetCursorBitmap();
	m_hCursor = CColorCursor::CreateCursorFromBitmap(aBMP,RGB(0,0,0),0,0);
	*/

	//Load up the file that was created earlier in the function into a bitmap
	//   then use that as the cursor.
	HBITMAP   hBMP; 
	HPALETTE palette;
	LoadBitmapFromBMPFile(L"capture.bmp", &hBMP, &palette);
	m_hCursor = CColorCursor::CreateCursorFromBitmap(hBMP,RGB(0,0,0),0,0);
	
	::SetCursor(m_hCursor); 
    
    //Clean up
done:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    //ReleaseDC(hdcScreen);
    //ReleaseDC(hdcWindow);
    //DeleteObject(hdcScreen);
    DeleteObject(hdcWindow);


    return 0;
}

and

C++
//////////////////////////////////////////////////////////////////////
//  CreateCursorFromBitmap 
//  Function to create a cursor from HBITMAP. 
//  Pass bitmaps having standard cursor sizes like 16*16, 32*32...
//////////////////////////////////////////////////////////////////////
HCURSOR CColorCursor::CreateCursorFromBitmap(HBITMAP hSourceBitmap,
											 COLORREF clrTransparent,
											 DWORD   xHotspot,DWORD   yHotspot)
{
	HCURSOR hRetCursor = NULL;

	do
	{
		if(NULL == hSourceBitmap)
		{
			break;
		}

		//Create the AND and XOR masks for the bitmap
		HBITMAP hAndMask = NULL;
		HBITMAP hXorMask = NULL;
		GetMaskBitmaps(hSourceBitmap,clrTransparent,hAndMask,hXorMask);
		if(NULL == hAndMask || NULL == hXorMask)
		{
			break;
		}

		//Create the cursor using the masks and the hotspot values provided
		ICONINFO iconinfo = {0};
		iconinfo.fIcon		= FALSE;
		iconinfo.xHotspot	= xHotspot;
		iconinfo.yHotspot	= yHotspot;
		iconinfo.hbmMask	= hAndMask;
		iconinfo.hbmColor	= hXorMask;

		hRetCursor = ::CreateIconIndirect(&iconinfo);

	}
	while(0);

	return hRetCursor;
}


I have used code from the following sources...


HOWTO: How To Use LoadImage() to Read a BMP File
at http://support.microsoft.com/kb/158898

and

Creating a color cursor from a bitmap
at Creating a color cursor from a bitmap

In the last article the author warns against making a cursor outside of the standard cursor sizes but this doesn't explain why the code works when loading a cursor from file but not when using the bitmap directly!

modified 21-Feb-13 4:05am.

QuestionHow Print multiple copies with printdlg in MFC Pin
haha_c20-Feb-13 21:06
haha_c20-Feb-13 21:06 
AnswerRe: How Print multiple copies with printdlg in MFC Pin
Richard MacCutchan20-Feb-13 21:13
mveRichard MacCutchan20-Feb-13 21:13 
GeneralRe: How Print multiple copies with printdlg in MFC Pin
haha_c20-Feb-13 21:54
haha_c20-Feb-13 21:54 
GeneralRe: How Print multiple copies with printdlg in MFC Pin
Richard MacCutchan20-Feb-13 22:39
mveRichard MacCutchan20-Feb-13 22:39 
GeneralRe: How Print multiple copies with printdlg in MFC Pin
haha_c20-Feb-13 23:31
haha_c20-Feb-13 23:31 
QuestionLoad an image dynamically in win32 using VC++ Pin
Sachin k Rajput 20-Feb-13 20:05
Sachin k Rajput 20-Feb-13 20:05 
AnswerRe: Load an image dynamically in win32 using VC++ Pin
_AnsHUMAN_ 20-Feb-13 20:56
_AnsHUMAN_ 20-Feb-13 20:56 
AnswerRe: Load an image dynamically in win32 using VC++ Pin
Richard MacCutchan20-Feb-13 22:32
mveRichard MacCutchan20-Feb-13 22:32 
GeneralRe: Load an image dynamically in win32 using VC++ Pin
Sachin k Rajput 21-Feb-13 0:27
Sachin k Rajput 21-Feb-13 0:27 
GeneralRe: Load an image dynamically in win32 using VC++ Pin
Richard MacCutchan21-Feb-13 1:14
mveRichard MacCutchan21-Feb-13 1:14 
AnswerRe: Load an image dynamically in win32 using VC++ Pin
Shaheed Legion26-Feb-13 5:10
Shaheed Legion26-Feb-13 5:10 
QuestionWhy does so many companies use directUI to show GUI ? Pin
yu-jian20-Feb-13 15:09
yu-jian20-Feb-13 15:09 
QuestionCFileDialog in Dll Project Pin
LeeUnSong20-Feb-13 14:38
LeeUnSong20-Feb-13 14:38 
AnswerRe: CFileDialog in Dll Project Pin
Richard MacCutchan20-Feb-13 21:10
mveRichard MacCutchan20-Feb-13 21:10 
GeneralRe: CFileDialog in Dll Project Pin
LeeUnSong21-Feb-13 0:31
LeeUnSong21-Feb-13 0:31 
GeneralRe: CFileDialog in Dll Project Pin
Richard MacCutchan21-Feb-13 1:16
mveRichard MacCutchan21-Feb-13 1:16 
QuestionFormatting Output Pin
Sarah Trattner20-Feb-13 12:02
Sarah Trattner20-Feb-13 12:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.