Click here to Skip to main content
13,198,563 members (30,430 online)

C / C++ / MFC

 
QuestionRe: CoCreateInstance fail for 64 bit Pin
Richard MacCutchan20-Feb-13 22:43
mvpRichard MacCutchan20-Feb-13 22:43 
AnswerRe: CoCreateInstance fail for 64 bit Pin
john563220-Feb-13 23:32
memberjohn563220-Feb-13 23:32 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Richard MacCutchan20-Feb-13 23:58
mvpRichard MacCutchan20-Feb-13 23:58 
GeneralRe: CoCreateInstance fail for 64 bit Pin
john563221-Feb-13 0:45
memberjohn563221-Feb-13 0:45 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Richard MacCutchan21-Feb-13 1:19
mvpRichard MacCutchan21-Feb-13 1:19 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Jochen Arndt21-Feb-13 0:53
memberJochen Arndt21-Feb-13 0:53 
GeneralRe: CoCreateInstance fail for 64 bit Pin
Chris Losinger22-Feb-13 4:14
memberChris Losinger22-Feb-13 4:14 
QuestionCursor from Bitmap Conundrum Pin
Ben Aldhouse20-Feb-13 21:36
memberBen 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...
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!

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

//////////////////////////////////////////////////////////////////////
//  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.

QuestionCFileDialog in Dll Project Pin
LeeUnSong20-Feb-13 14:38
memberLeeUnSong20-Feb-13 14:38 
AnswerRe: CFileDialog in Dll Project Pin
Richard MacCutchan20-Feb-13 21:10
mvpRichard MacCutchan20-Feb-13 21:10 
GeneralRe: CFileDialog in Dll Project Pin
LeeUnSong21-Feb-13 0:31
memberLeeUnSong21-Feb-13 0:31 
GeneralRe: CFileDialog in Dll Project Pin
Richard MacCutchan21-Feb-13 1:16
mvpRichard MacCutchan21-Feb-13 1:16 
QuestionBOM Code Pin
Michael Haephrati מיכאל האפרתי20-Feb-13 10:41
mvpMichael Haephrati מיכאל האפרתי20-Feb-13 10:41 
SuggestionRe: BOM Code Pin
DavidCrow20-Feb-13 10:47
memberDavidCrow20-Feb-13 10:47 
GeneralRe: BOM Code Pin
Michael Haephrati מיכאל האפרתי20-Feb-13 10:49
mvpMichael Haephrati מיכאל האפרתי20-Feb-13 10:49 
QuestionUsing C++ TagLib, not TagLib Sharp - how to write APIC frames Pin
Steve S19-Feb-13 6:32
memberSteve S19-Feb-13 6:32 
AnswerRe: Using C++ TagLib, not TagLib Sharp - how to write APIC frames Pin
Steve S19-Feb-13 7:21
memberSteve S19-Feb-13 7:21 
Questionglut project Pin
abhi sharma19-Feb-13 2:02
memberabhi sharma19-Feb-13 2:02 
AnswerRe: glut project Pin
Richard MacCutchan19-Feb-13 3:06
mvpRichard MacCutchan19-Feb-13 3:06 
QuestionCreate a program to encrypt and decrypt binary files using S-DES (Simplified DES) in the Cipher Block Chaining mode. Pin
ymadhu336618-Feb-13 7:16
memberymadhu336618-Feb-13 7:16 
AnswerRe: Create a program to encrypt and decrypt binary files using S-DES (Simplified DES) in the Cipher Block Chaining mode. Pin
Richard MacCutchan18-Feb-13 7:56
mvpRichard MacCutchan18-Feb-13 7:56 
QuestionWinHelp not working properly in MFC Pin
vermaashish_mca18-Feb-13 3:01
membervermaashish_mca18-Feb-13 3:01 
QuestionHow to execute java exe in VC++ 2010 ? Pin
IICTECH17-Feb-13 22:41
memberIICTECH17-Feb-13 22:41 
AnswerRe: How to execute java exe in VC++ 2010 ? Pin
Richard MacCutchan17-Feb-13 22:42
mvpRichard MacCutchan17-Feb-13 22:42 
GeneralRe: How to execute java exe in VC++ 2010 ? Pin
IICTECH18-Feb-13 0:26
memberIICTECH18-Feb-13 0:26 

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.


Advertise | Privacy |
Web03 | 2.8.171020.1 | Last Updated 18 Oct 2017
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid