|
One way is to pass the the associated handles around. They all have in common a HGDIOBJ.
You can use the Attach() and Detach() methods to associate/disassociate the HGDIOBJ with an MFC
CGdiObject object.
Mark
|
|
|
|
|
Thanks Mark, can you show me an example of how to do this?
Thanks,
BP
|
|
|
|
|
Here's 1 way - sharing the GDI object between instances of a class:
class CMyClass
{
CBitmap Bitmap;
public:
CMyClass() {}
CMyClass(const CMyClass &);
};
CMyClass::CMyClass(const CMyClass &src)
{
Bitmap.Attach(src.Bitmap.m_hObject);
} This is not necessarily a good idea since there's no way of tracking the use of the shared object.
IMO a better method is to create new objects for each instance of the class:
class CMyClass
{
CBitmap Bitmap;
void CreateGDIObjects();
public:
CMyClass() {CreateGDIObjects();}
CMyClass(const CMyClass &);
};
CMyClass::CMyClass(const CMyClass &src)
{
CreateGDIObjects();
}
void CMyClass::CreateGDIObjects()
{
Bitmap.LoadBitmap(...);
}
You could also write the code to clone the GDI objects by extracting enough info from the objects
to create a duplicate object. Too bad MFC doesn't have that already
|
|
|
|
|
Thanks Mark, the information you have provided has been very helpful.
BP
|
|
|
|
|
You're welcome
The more I think about that first example, the less I like it. If you absolutely MUST share the
same GDI objects between instances of a class then maybe this is a better solution (note that
it's NOT thread safe);
class CMyClass
{
static DWORD RefCount;
static CBitmap Bitmap;
public:
CMyClass();
~CMyClass();
CMyClass(const CMyClass &);
};
DWORD CMyClass::RefCount = 0;
CMyClass::CMyClass()
{
if (RefCount == 0)
Bitmap.LoadBitmap(...);
RefCount++;
}
CMyClass::CMyClass(const CMyClass &src)
{
RefCount++;
}
CMyClass::~CMyClass()
{
RefCount--;
if (RefCount != 0)
Bitmap.Detach();
}
|
|
|
|
|
Thanks again Mark.
I am wondering, is there perhaps a different strategy that I should use. Since all the images will be imported as resources, should I just have variables to remember the different GDI object settings and then instantiate them using those variables rather than attempting to copy them. What do you think about that strategy? How hard would it be to do that? Could I do it using a LOG structure (i.e. LOGPEN or LOGBRUSH).
Thanks,
BP
|
|
|
|
|
hmm...
For pens, brushes, fonts there's not much problem. They can be selected into multiple DCs and
they don't change. Thus, they can be kept around like a "GDI toolbox" and used as needed.
Bitmaps will be the trouble. They can only be selected into one memory DC at a time.
I guess it depends how they're used...
For high-performance situations like "sprites" being blt'd often in animation you may want to
keep them selected into a memory DC for fast blting, so you'll need a copy for each DC.
For low-performance situations (for example, the bitmaps only get redrawn when a WM_PAINT event
occurs) then one bitmap used by all is fine. A bitmap could be selected into a DC, Bltd, and de-
selected from a DC as needed. If this is done by multiple threads then a simple sync object can
be used to prevent use in more than one dc at a time.
Mark
|
|
|
|
|
Indeed, how do I "keep them around" between classes and select them into the DC? I am also thinking about using pointers and "new". Would smart pointers help?
Is there another image class I can use that would make it easier (i.e. CImage or something here on CodeProject that you know works well)?
Thanks again,
BP
|
|
|
|
|
BlitzPackage wrote: Is there another image class I can use that would make it easier
No matter what class you wrap them in you'll still have the same issue, so use whatever is best
for your situation I'd say .
If your plan is to share one copy application-wide then yes, you'll probably want an implementation similar to a smart pointer. You'll also need a way to track when a bitmap is "in use" (selected into a DC). You could wrap them in a class that combines smart-pointer
functionality with some kind of indicator or sync object for thread syncronization if necessary.
|
|
|
|
|
Thanks Mark, I appreciate all your help.
BP
|
|
|
|
|
hi i want to make an application that draws on screen i mean "real desktop",i had made drawing on another window it works fine for that,now how to draw on the desktop.
any help is welcomed.
Regards.
Tasleem Arif
|
|
|
|
|
use
HDC hDesktopDC = GetDC(GetDesktopWindow());
then draw on that DC, instead of your window DC.
|
|
|
|
|
I think this kind of thing will not work efficiently when the Aero desktop is enabled in Vista.
Steve
|
|
|
|
|
directly trying to draw on desktop window ( GetDesktopWindow() )may not work due to unavailablity of the OnPaint kind of messages for this kind of application (unless some kind of explorer hacking is done !)
a suggested way could be drawing on a transparent window which does not have no caption, menu, frame etc.
|
|
|
|
|
You can draw on the desktop any time you want! You just need the right DC
HDC hScreenDC = ::GetDC(0);
Sometimes it's fun to just trash the desktop
Maybe I need to get out more...
|
|
|
|
|
Drawing on a transparent window may be a better approach.
Steve
|
|
|
|
|
Hi everyone,
I'm trying to add a tooltip to my buttons on a toolbar,but without any luck.I checked it out with spy++ and HWND seems valid,but i can't activate the tool tip.According to documentation stuff,I do not have to write a message handler for my tooltips to be displayed (I use the TTF_SUBCLASS flag),am I wrong,or missing something in the code below?
<br />
RECT rect;<br />
HWND hwndTT;<br />
INITCOMMONCONTROLSEX iccex;<br />
ATLVERIFY((SendMessage(hwndParent,TB_GETITEMRECT,(WPARAM) iButton,(LPARAM) (LPRECT)&rect)) == TRUE);
<br />
iccex.dwICC = ICC_WIN95_CLASSES;<br />
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);<br />
InitCommonControlsEx(&iccex);<br />
if ((hwndTT = CreateWindowEx(<br />
WS_EX_TOPMOST,<br />
TOOLTIPS_CLASS,<br />
NULL,<br />
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,<br />
CW_USEDEFAULT,<br />
CW_USEDEFAULT,<br />
CW_USEDEFAULT,<br />
CW_USEDEFAULT,<br />
hwndParent,<br />
NULL,<br />
NULL,<br />
NULL<br />
)) == NULL)<br />
return NULL;<br />
<br />
::SetWindowPos(hwndTT,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);<br />
<br />
TOOLINFO ti;<br />
ti.cbSize = sizeof(TOOLINFO);<br />
ti.uFlags = TTF_SUBCLASS;<br />
ti.hwnd = hwndParent;<br />
ti.lpszText = (LPTSTR) lpszText;<br />
<br />
ti.rect.bottom = rect.bottom;<br />
ti.rect.left = rect.left;<br />
ti.rect.top = rect.top;<br />
ti.rect.right = rect.right;<br />
<br />
SendMessage(hwndTT,TTM_SETDELAYTIME,TTDT_INITIAL,0L);<br />
return SendMessage(hwndTT,TTM_ADDTOOL,0,(LPARAM)&ti);<br />
|
|
|
|
|
please when posting a piece of code, to use the <pre> tag instead of the <code> one.
thanks
|
|
|
|
|
ajitatif angajetor wrote: SendMessage(hwndTT,TTM_SETDELAYTIME,TTDT_INITIAL,0L);
You have passed delay time value(LPARAM) as 0. Is it intentional ?
For setting default delay it should be -1.
|
|
|
|
|
prasad_som wrote: You have passed delay time value(LPARAM) as 0. Is it intentional ?
Yes,to pop the ToolTip up instantly,so I can see the rectangle is exactly as I meant it to be.
|
|
|
|
|
Code is looking ok to me. Can you show how you have created toolbar ?
|
|
|
|
|
uh,i had to hack my code much more throughly to see it was all about rectangles.i found out that the toolbar had one of the items resized after i created the tooltip (with the wrong rectangles).
and i added a TB_SETTOOLTIPS message right after the TTM_ADDTOOL .works just fine now,thanks for everything
|
|
|
|
|
Dear All,
I have created one ATL Service program. Inside that i have done thread and socket operations. I registered this service in my syatem WinXP using the below cmd..
sc create "filename.exe" binpath= "c:\filename.exe"
But my problem is that I started my service program. It is showing tha "The service did not respond start request"
When I see TaskManager, I can see my program is running.. How this is happening ..?
Kindly do help
Thanks
Nice things do nice works
|
|
|
|
|
The application needs to set its service status so that the SCM knows what is going on with it. Look up SetServiceStatus(...) for more information.
Peace!
-=- James Please rate this message - let me know if I helped or not!<HR> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
Hello friends...
I am working with vc++6.Now i wanted to restart my MFC application from within itself.How can i make it possible.
Please help me
Thanks
|
|
|
|