|
|
I am working on a drawing application using MFC and GDI+.
Now I am checking the following method
virtual BOOL OnDraw(CDC* pDC, CSize& rSize);
in my class derived from COleServerItem.
(This method is called to draw OLE item to metafile by framework.)
In this method, (actually pDC is pointer to CMetaFileDC object.)
following code
Metafile mf(pDC->m_hDC);
is failed, as lastResult = GenericError
also,
Graphics g(pDC->m_hDC);
is failed, as lastResult = OutOfMemory
Naturally, GDI grawing using pDC is OK.
How do I manipulate pDC with GDI+?
My environment is Visual Studio 2003 Version 7.1.3091.
If anyone has any suggestions about what I am doing wrong,
it would be greatly appreciated!
|
|
|
|
|
shinano wrote: Graphics g(pDC->m_hDC
Whats pDC? CDC or CMetaFileDC
|
|
|
|
|
Thanks,
pDC is a pointer to CMetaFileDC object.
I checked it by debugger.
|
|
|
|
|
Is your problem solve?if not how to create CMetaFileDC?
|
|
|
|
|
The method
virtual BOOL OnDraw(CDC* pDC, CSize& rSize);
is called by framework to draw a OLE item to a metafile.
so, CMetaFileDC object is created by framework.
According to MFC library reference "COleServerItem::OnDraw".
-- modified at 20:15 Sunday 17th September, 2006
GDI+ can record metafiles in the EMF and EMF+ formats, but not in the WMF format.
according to "Metafiles in GDI+"
http://msdn2.microsoft.com/en-us/library/zbk7dbtb.aspx
But OnDraw's pDC is Windows Metafile (WMF) .
So, we cannot use GDI+ in COleServerItem::OnDraw.
|
|
|
|
|
I'm creating a custom control which has a child control. My custom control draws a border and positions the child control.
When the parent control scrolls, it moves the child control to give the appearance of scrolling.
The problem is, when part of the child control goes beyond the edge of the parent control, it overdraws the border.
How can I go about limiting where the child control can draw? Is there some clipping I need to do, adjusting the clipping dynamically as I move the child around?
I've tried a few things with clipping with no luck. Any ideas?
|
|
|
|
|
I am just beginning at this stuff, but after long hours... here is how I managed to clip child windows:
<br />
..... OnPaint(....)<br />
{<br />
::GetClientRect(m_hWnd,&test_rect);<br />
<br />
::GetClientRect(m_ReadRssWnd,&bk_rect);<br />
<br />
hRgn2= CreateRectRgn(test_rect.right/3,test_rect.top,test_rect.right-300,test_rect.bottom);<br />
hRgn = CreateRectRgn(bk_rect.left+200,bk_rect.top,bk_rect.right-100,bk_rect.bottom);<br />
<br />
hDC2 =::BeginPaint(m_hWnd,&ps2);<br />
hDC =::BeginPaint(m_ReadRssWnd,&ps);<br />
<br />
::SelectClipRgn(hDC2,hRgn2);<br />
::SelectClipRgn(hDC,hRgn); <br />
<br />
::SetTextColor(hDC,RGB(255,255,255)); <br />
::SetBkColor(hDC,RGB(255,0,0));<br />
<br />
::FillRect(hDC2,&test_rect,hBr2); <br />
::FillRect(hDC,&bk_rect,hBr);<br />
<br />
::EndPaint(m_ReadRssWnd,&ps);<br />
::EndPaint(m_hWnd,&ps2);<br />
<br />
return 0;<br />
}
Now, this is probably not the best solution (or even the right one), but you will get your clip regions...
Now, if you could help me with my problem... just take a look at the message above "EraseBacgnd - mfranco_neto".
Thanks in advance
Mfranco
|
|
|
|
|
Hey,
I've a MFC-Based DLL calling a special drawing function in another DLL (MFC extended). All works fine in debug-mode. But when I tried to test my DLL in release mode, the program crashes in the line with SetMapMode.
Function in calling DLL (OnPaint):
...<br />
CPaintDC dc(this);<br />
<br />
PaintSpecialGraphics(&dc);<br />
...
Function in DLL:
int WINAPI PaintSpecialGraphics(CDC *pDC)<br />
{<br />
...<br />
pDC->SetMapMode(MM_LOMETRIC); <<<< CRASH !!!<br />
...<br />
}
Thanx for your help.....
P.S: When I try to call the "PaintSpecialGrafics" from my Application (.exe) all works fine...
-- modified at 18:09 Thursday 31st August, 2006
|
|
|
|
|
First I'd make sure you're building the release build with debug info. Follow these steps in MSVC 6:
- Select "Project->Settings...".
- Select the "Release" configuration.
- Select "C/C++" tab.
- Select "General" in the "Category" combo.
- In the "Debug info" combo select "Program Database".
- Select the "Link" tab.
- Select "Debug" in the "Category" in combo.
- Tick "Debug info" and "Separate types" and choose "Microsoft format".
- Select OK.
- Rebuild all.
If you're using a newer version of visual studio you'll have to adjust these steps.
Now reproduce the error are see where the error occurs in the MFC source code; this might give you more chance of understanding what's going wrong.
Steve
|
|
|
|
|
I suspect it's due to the passing of the DC object between two DLLs, but I can't be sure where exactly the problem is. To narrow it down, check the following:
1) Check the validity of pointer pDC in PaintSpecialGraphics(CDC *pDC);
2) Add thhis code to the calling DLL and see if it works locally:
CDC* pDC = &dc;
pDC->SetMapMode(MM_LOMETRIC);
3) To further test, you could change the function signature from PaintSpecialGraphics(CDC *pDC) to PaintSpecialGraphics(CPaintDC &dc).
Etc.
Best,
Jun
|
|
|
|
|
I suspected the same thing but, like you, can't pinpoint the exact problem. That's why I think knowing where things go wrong inside MFC might help.
Perhaps it's possible that different compiler settings were used in the EXE and the DLL and this caused the layout of the CDC class differ.
Or perhaps it's a mixed allocator problem: class CDC in the EXE allocates some data on its heap the the DLL free it on a different heap.
It would probably be a good idea to pass the raw HDC when passing a DC between modules.
Steve
|
|
|
|
|
OK, the error is in the CDC class. The compiler stops in the function OffsetViewportOrg!
|
|
|
|
|
Perhaps you can quote the file/line (and MFC version) and paste in some code surrounding the fault.
Steve
|
|
|
|
|
Ok, here is the function where the debugger stops (wingdi.cpp, MFC 7.1, VS2003 SP1):
CPoint CDC::SetViewportOrg(int x, int y)<br />
{<br />
ASSERT(m_hDC != NULL);<br />
CPoint point;<br />
<br />
if (m_hDC != m_hAttribDC)<br />
VERIFY(::SetViewportOrgEx(m_hDC, x, y, &point));<br />
if (m_hAttribDC != NULL)<br />
VERIFY(::SetViewportOrgEx(m_hAttribDC, x, y, &point));<br />
return point; <<<<<<<<<<<<<<<<Here stops the debugger !!!???<br />
}
I can't imagine why the debugger/program stops at this line...?
|
|
|
|
|
Thank you for your answer, I tried your recommendation...
1) --> Pointer is valid
2) --> works fine
3) --> ?
|
|
|
|
|
I suggest you side step the problem as follows:
1. Change the signature of the DLL function as follows:
int WINAPI PaintSpecialGraphics(HDC hDC);
2. Adjust the implementaion in the DLL so it looks like this:
int WINAPI PaintSpecialGraphics(HDC hDC)
{
CDC dc;
dc.Attach(hDC);
dc.Detach();
}
3. Make the call like this:
CPaintDC dc(this);
PaintSpecialGraphics(dc);
I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons:
- MFC's handle map implementation.
- Different heaps.
- Different compiler settings in EXE and DLL.
Steve
|
|
|
|
|
Stephen Hewitt wrote: I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons:
- MFC's handle map implementation.
- Different heaps.
- Different compiler settings in EXE and DLL.
Does this mean, that there is no way to exchange data (pointer to mfc objects) between mfc dlls?
My concept is to exchange cobject dervied classes (pointer) between my application and a mfc-based calculation dll..
|
|
|
|
|
It depends on how the classes are implemented and packaged. Consider this example:
class CExample
{
public:
int GetNum() { return g_Number; }
}
In this class the CExample::GetNum method access a global variable. If you include this class into an EXE and a DLL then the version in the EXE will access a global in the EXE; but when called from the DLL it will access a global (of the same name) in the DLL. Problems will probably ensue. There are ways around this issue but perhaps the MFC classes are simply not designed to be passed between module boundries (like this class). Unless you know it is same to do this the only safe assumption is that you can't.
Steve
|
|
|
|
|
Hi!
I have a problem with a button I have created dynamically in an SDI application in MFC.
Its purpose is to terminate the application (an Exit button). It works perfectly when I click on it, but what I want to do is make it close my application when I press the Enter key. It just doesn't work, even though the button has focus. It works when I have a dialog based application, but I'm not interested in that. I want it to be an SDI application. A solution I have found is to close the application by calling PostQuitMessage method when I press the Enter key and my button has focus, but I'm interested in a more simple and elegant way if possible.
Any ideas would be greatly apreciated!
Thanks in advance!
|
|
|
|
|
One way is, make that button of type CMyButton, derived from CButton, handle WM_KEYDOWN message.
-- modified at 3:00 Friday 1st September, 2006
|
|
|
|
|
|
Hi all.
How I prevent others to access my process via interprocess communication?
I know that when I want to open a process using IPC I can use OpenProcess function and inform the desired access. How I can prevent every access, i.e., no PROCESS_VM_READ access, no PROCESS_VM_WRITE acess, etc etc.
And, How i can deny ipc access for all process but allow it to a specif process?
Thx in advance.
Best regards,
Marco Alves.
|
|
|
|
|
First, the process access as you described is not IPC. It's usually controlled by process's security attributes. You may call SetSecurityInfo() to define security of a process. Hope this link can help.
On the other hand, IPC is the communication between two processes. Thus, it's mutual. If your process does not respond to IPC, nobody can do anything to hurt it.
Best,
Jun
|
|
|
|
|
In a recent post Jeremy Falcon[^] provided a link to a white paper about DLL best practices. Basically the paper outlined the does and don'ts of the DllMain function. One of the references cited in that paper is http://blogs.msdn.com/oldnewthing/archive/2004/01/27/63401.aspx[^] where the author says never create a window in response to DLL_PROCESS_ATTACH.
Now this brings up a question in my mind. I have a dll where I have declared a global class that calls the CreateWindow() API in it's constructor. While the window is technically not created in DllMain, it does get created every time the dll is loaded but before DllMain is called.
Everything seems to be working fine so far, but am I asking for trouble using this approach? Or is the fact the window is not created in DllMain mean that I am avoiding the locking issues mentioned in those papers? I guess my question can be summed up as: Is this a safe way to create global window objects in a dll?
Global class:
class CDllWindow
{
public:
CDllWindow();
private:
HWND DllWindow;
};
CDllWindow::CDllWindow()
{
DllWindow = CreateWindow(...);
}
Dll cpp file:
#include "DllWindow.h"
CDllWindow DllWindow;
BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID)
{
return TRUE;
}
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|