Sharing a HBITMAP between 2 applications [modified]
-
Hello and good day. I have 2 applications wherein I want the 1st which creates a graph send its image to the 2nd which will display it. I searched for some ways and ended up using a MFC shared DLL wherein I have a HBITMAP which the 1st one will write image on, and the 2nd one will read (using WM_COPYDATA for signalling, and mutex for synch). It's declared as the ff:
#pragma bss_seg("MFCDLLSample") TESTDLL_API HBITMAP DLLImageBmp; #pragma bss_seg()
Now, I checked first if it works by having the 1st app make a graph then display it on another picture box (same app) and it actually worked. When I tried to display it in the 2nd, it does not display. I coded it like this in the 2nd app:
//obtain the CDC handle for the picture box PicWnd = GetDlgItem(IDC_PICBOX); PicDC = PicWnd->GetDC(); oldBmp = (HBITMAP)PicDC->SelectObject(DLLImageBmp); PicPaintDC.BitBlt(0, 0, 404, 404, PicDC, 0, 0, SRCCOPY); CDialog::OnPaint();
Can anyone help me out with this? I really need to know what might be wrong with my code or implementation. Thank you in advance for the help and time! --added contents: I forgot, TESTDLL_API's definition is this:
#ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif
Thanks again!
modified on Monday, June 23, 2008 12:48 AM
-
Hello and good day. I have 2 applications wherein I want the 1st which creates a graph send its image to the 2nd which will display it. I searched for some ways and ended up using a MFC shared DLL wherein I have a HBITMAP which the 1st one will write image on, and the 2nd one will read (using WM_COPYDATA for signalling, and mutex for synch). It's declared as the ff:
#pragma bss_seg("MFCDLLSample") TESTDLL_API HBITMAP DLLImageBmp; #pragma bss_seg()
Now, I checked first if it works by having the 1st app make a graph then display it on another picture box (same app) and it actually worked. When I tried to display it in the 2nd, it does not display. I coded it like this in the 2nd app:
//obtain the CDC handle for the picture box PicWnd = GetDlgItem(IDC_PICBOX); PicDC = PicWnd->GetDC(); oldBmp = (HBITMAP)PicDC->SelectObject(DLLImageBmp); PicPaintDC.BitBlt(0, 0, 404, 404, PicDC, 0, 0, SRCCOPY); CDialog::OnPaint();
Can anyone help me out with this? I really need to know what might be wrong with my code or implementation. Thank you in advance for the help and time! --added contents: I forgot, TESTDLL_API's definition is this:
#ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif
Thanks again!
modified on Monday, June 23, 2008 12:48 AM
GDI handles cannot be shared across process. You have to think of some alternative methods to transfer the image from the first process to next. A possible method is sending the pixel data of the bitmap to the second process and the second process should recreate the bitmap using the pixel data. 1) you can use
GetDIBits()
function to get the pixel data of a bitmap 2) useWM_COPYDATA
or other interprocess communication methods to send the pixel data to the second process. 3. useCreateDIBitmap()
function to recreate the bitmap.nave [OpenedFileFinder]
-
GDI handles cannot be shared across process. You have to think of some alternative methods to transfer the image from the first process to next. A possible method is sending the pixel data of the bitmap to the second process and the second process should recreate the bitmap using the pixel data. 1) you can use
GetDIBits()
function to get the pixel data of a bitmap 2) useWM_COPYDATA
or other interprocess communication methods to send the pixel data to the second process. 3. useCreateDIBitmap()
function to recreate the bitmap.nave [OpenedFileFinder]
-
Llasus wrote:
I was adviced last time to do that. Please refer to this link[^].
I am also confused seeing that. :confused: AFAIK, it cannot be shared.
From MSDN:
"_GDI objects support only one handle per object. Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle_"
The GDI handles are actually offset to the handle map's that reside in the client side. So when you pass a handle to another process, it simply points to a location in the handle table in that process. Some times, the object in that location will be entirly a different one such as Brush or Pen or some times the object itself is not created. So the result will be unpredictable. if you want to know more please read the article Give Me a Handle, and I'll Show You an Object[^]nave [OpenedFileFinder]
-
Llasus wrote:
I was adviced last time to do that. Please refer to this link[^].
I am also confused seeing that. :confused: AFAIK, it cannot be shared.
From MSDN:
"_GDI objects support only one handle per object. Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle_"
The GDI handles are actually offset to the handle map's that reside in the client side. So when you pass a handle to another process, it simply points to a location in the handle table in that process. Some times, the object in that location will be entirly a different one such as Brush or Pen or some times the object itself is not created. So the result will be unpredictable. if you want to know more please read the article Give Me a Handle, and I'll Show You an Object[^]nave [OpenedFileFinder]
Naveen wrote:
I am also confused seeing that. [Confused]
Guess I trusted that advice too early, even though I had a doubt in my mind if it was possible in the first place. Anyway, I'll read the article to have more knowledge on this and try coding the solution that you gave me earlier on. Thank you very much for your help and time! :)
-
Naveen wrote:
I am also confused seeing that. [Confused]
Guess I trusted that advice too early, even though I had a doubt in my mind if it was possible in the first place. Anyway, I'll read the article to have more knowledge on this and try coding the solution that you gave me earlier on. Thank you very much for your help and time! :)
-
Llasus wrote:
I was adviced last time to do that. Please refer to this link[^].
I am also confused seeing that. :confused: AFAIK, it cannot be shared.
From MSDN:
"_GDI objects support only one handle per object. Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle_"
The GDI handles are actually offset to the handle map's that reside in the client side. So when you pass a handle to another process, it simply points to a location in the handle table in that process. Some times, the object in that location will be entirly a different one such as Brush or Pen or some times the object itself is not created. So the result will be unpredictable. if you want to know more please read the article Give Me a Handle, and I'll Show You an Object[^]nave [OpenedFileFinder]
-
:(( Sorry for the advice man but i was really not aware of the fact that handles cant be shared across the processes.
Regards, Sandip.
-
:)
nave [OpenedFileFinder]
-
Hello and good day. I have 2 applications wherein I want the 1st which creates a graph send its image to the 2nd which will display it. I searched for some ways and ended up using a MFC shared DLL wherein I have a HBITMAP which the 1st one will write image on, and the 2nd one will read (using WM_COPYDATA for signalling, and mutex for synch). It's declared as the ff:
#pragma bss_seg("MFCDLLSample") TESTDLL_API HBITMAP DLLImageBmp; #pragma bss_seg()
Now, I checked first if it works by having the 1st app make a graph then display it on another picture box (same app) and it actually worked. When I tried to display it in the 2nd, it does not display. I coded it like this in the 2nd app:
//obtain the CDC handle for the picture box PicWnd = GetDlgItem(IDC_PICBOX); PicDC = PicWnd->GetDC(); oldBmp = (HBITMAP)PicDC->SelectObject(DLLImageBmp); PicPaintDC.BitBlt(0, 0, 404, 404, PicDC, 0, 0, SRCCOPY); CDialog::OnPaint();
Can anyone help me out with this? I really need to know what might be wrong with my code or implementation. Thank you in advance for the help and time! --added contents: I forgot, TESTDLL_API's definition is this:
#ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif
Thanks again!
modified on Monday, June 23, 2008 12:48 AM
Why you dont use of WM_COPYDATA?Inter-Process Communication using WM_COPYDATA[^].
-
Why you dont use of WM_COPYDATA?Inter-Process Communication using WM_COPYDATA[^].
Hamid. wrote:
Why you dont use of WM_COPYDATA?Inter-Process Communication using WM_COPYDATA[^].
Thank you for the suggestion. I am looking into it right now but the size of the bitmap bits actually is not a constant value. So I'll be needing a pointer for that in which WM_COPYDATA can't be used. I'm still checking some other routes like named pipes, or shared memory. Any further suggestions? Thank you!