|
I found what the problem is.
I tried to resize the window with DC still attached to it. That's why I had the assertion failure.
I added this code before resizing:
if (dcGraphMem.m_hDC != NULL)
dcGraphMem.DeleteDC();
and this after resizing:
CDC * pDC = GetDC();
if (dcGraphMem.m_hDC == NULL)
dcGraphMem.CreateCompatibleDC(pDC);
and now it works OK.
Thank you all for your help.
|
|
|
|
|
You should not be holding a DC like this in the first place. You only need a DC at the time you need to display anything, which is in your OnPaint() function, it has no purpose when resizing.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
If you have to do this... you may be resizing the window in a method where it's not appropriate to do so. See Richard's comment about the device context. You should only be holding the DC when you're actually doing any GDI drawing, otherwise, it should be released. That's sort of what's causing your problem in the first place, you're making a call to a method that requires the DC when you're already holding it up.
Hope you understand all this gibberish... good luck!
|
|
|
|
|
Well I'm not holding the DC. What I do is open DC in the InitDialog for short time only to create compatibile memory DC, and then I draw my graph in memory DC. When necessary I open the DC again and copy the memory DC into DC.
if (dcGraphMem.m_hDC == NULL) {
CDC * pDC = GetDC();
dcGraphMem.CreateCompatibleDC(pDC);
ReleaseDC(pDC) ;
}
then I operate on dcGraphMem and when it's ready I do that:
CDC * pDC = GetDC();
if(pDC == NULL)
{
return;
}
pDC->BitBlt(0, 0, GraphWindow.Width(), GraphWindow.Height()-BOTTOMCONTROLS-2, &dcGraphMem, 0, 0, SRCCOPY);
ReleaseDC(pDC);
I thought that memory DC is not linked with window directly, however it looks like I need to delete it before I resize the window, and then create it again. Why is that?
|
|
|
|
|
You don't need to delete it, you just can't hold it up, it's not hooked to the window directly, but your application won't be able to attach to the drawing context twice (it will eventually fail, as you've found out). You also should be drawing on your InitDialog() (this is for initializing controls really), that's not the proper place for that.
Any drawing should occur on OnPaint(), alternatively, no resizing should occur within OnPaint() (can't think of any legitimate reason to do so). Reason to keep all drawing in OnPaint()... that's the method the framework will call every time the framework determines your window needs to be redrawn, for whatever reason, anything from a resize to a window getting placed over your window then removed, etc, will trigger a call to OnPaint().
|
|
|
|
|
blackbolek wrote: The SetWindowPos() function doesn't return ...
The call to ScreenToClient() is changing the values in rc so that is not going to do what you want.
blackbolek wrote: I also checked than 'this' pointer is not corrupted by checking the window text:
But you did not call it with the this pointer so the code is not the same as all your other calls to windows functions.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
To add on to what Richard said... using this on a window object is not the same as using it's handle. Reason is, this refers to the object instance and not the handle to the window, which is different (they are linked together when a window is created, not when the object is created, but even then, they are not the same).
...Just in case in needs to be clarified....
|
|
|
|
|
With ScreenToClient() commented off it gives me still the same 'Debug Assertion Failed' message.
Also I've modified the line which gets the window title to this:
::GetWindowText (this->m_hWnd, title, sizeof(title));
And I still get proper window title.
|
|
|
|
|
blackbolek wrote: ::GetWindowText (this->m_hWnd, title, sizeof(title));
and that is how I would attempt to get and set window position and size too, with an explicit hWnd, and not trough this->...
|
|
|
|
|
You need to get your debugger working and check exactly where this assertion occurs and which variable it is complaining about. Also you should be calling these Windows functions via the class methods. If ::GetWindowText() works as shown above then it should also work with the following:
GetWindowText(title, sizeof(title));
which is the correct way to code it.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Hi,
This is in reference to a MFC COM project I'm working on VC6.
The question is in regard to the top level menu.
The project contains a top level menu, say "Options"
I need to do certain “operations”, say toggle a BOOL value when the menu pane is open and when the menu pane is closed.
On selecting “Options”, WM_INITMENUPOPUP message is received and I can handle the functionality under this and make the BOOL variable TRUE.
The issue arises when the menu pane closes without selecting any menu option, I do not receive any windows message to handle and there is no confirmation that the menu pane is closed. Hence no location to toggle the BOOL variable.
I’ve checked on WM_UNINITMENUPOPUP message, but this message is not handled for VC6.
I’ve tried to retrieve the HMENU handle to the menu, but this is not possible as the menu is created in a different project altogether and hence I cannot use MENUBARINFO structure to find out if the menu is open or not.
Hence, the current challenge I face is whether or not the menu pane has been closed.
Is there any way to know if the menu pane is visible using the ids of the menu items or any other approach?
Thanks in advance for your thoughts
Regards,
Ravish
|
|
|
|
|
How about WM_EXITMENULOOP[^]?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
I programatically write an information into system event log ... and goes well, except that I read this in event viewer :
The description for Event ID 1 from source TestEventLog cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.
If the event originated on another computer, the display information had to be saved with the event.
The following information was included with the event:
My test message
the message resource is present but the message is not found in the string/message table
and my message is only 'My test message' ... why don't I see only my message ?
|
|
|
|
|
This link should help you solve your problem. [^]
Every new day is another chance to change your life.
|
|
|
|
|
Hi all, I want to know WinSNMP supports which versions of SNMP. Please share some info.
Regards
msr
|
|
|
|
|
What has this to do with C++, and have you tried Google?
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
|
Hi
I have writen a TAPI program that can call (works fine)
I want to speak via headset not picking up a phone.
I can do this with Venta Fax & Voice program in my PC (so the modem supports this), but my program can not do this (no sounds send/receive).
I have a full-duplex modem.
Is there any tricks in TAPI function for this?
I have used
LINEMEDIAMODE_AUTOMATEDVOICE for lineOpen function like this:
lineOpen(m_hLineApp, m_nDevID, &m_hLine, dwTAPIVer, 0, 1, LINECALLPRIVILEGE_MONITOR | LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_AUTOMATEDVOICE, NULL);
I've found that I should use PhoneApp for taking control of mic/speaker, but nothing changed!
int ret = phoneSetHookSwitch(m_hPhone, PHONEHOOKSWITCHDEV_SPEAKER, PHONEHOOKSWITCHMODE_MICSPEAKER);
m_hPhone is a HPHONE object
Please Help!
Regards
www.logicsims.ir
|
|
|
|
|
Hi again,
I am using data_segs to share an LPSTR variable but the sharing only seems to work with multiple instances of the same EXE - literally. When I retrieve the value of the var from another app, a different EXE, I get the default value of the variable originally initialized in the module.
Code in DLL:
#pragma data_seg("Shared")
__declspec(dllexport) LPSTR lpsCommandParameter = NULL;
#pragma data_seg()
#pragma comment(linker,"/SECTION:Shared,S")
extern "C"
{
__declspec(dllexport) VOID SetCommandParameter(LPSTR lpsParam);
__declspec(dllexport) LPSTR GetCommandParameter();
}
VOID SetCommandParameter(LPSTR lpsParam)
{
lpsCommandParameter = lpsParam;
}
LPSTR GetCommandParameter()
{
return lpsCommandParameter;
}
Code in Form1.cpp (Form1.exe) - Button1_Click - This button sets the value of lpsCommandParameter to "Hello"
typedef VOID (*pSetCommandParameter)(char *lpsParam);
HINSTANCE DllHandle = LoadLibraryW(L"my.dll");
if (DllHandle == NULL)
{
ShowMessage("NULL");
return;
}
pSetCommandParameter pSetParam = (pSetCommandParameter)GetProcAddress(DllHandle, "SetCommandParameter");
if (pSetParam == NULL)
{
ShowMessage("pSetParam is NULL");
return;
}
pSetParam("Hello");
Code in Form1.cpp (Form1.exe) - Button2_Click - This one retrieves the value of lpsCommandParameter:
typedef char *( *pGetCommandParameter )();
HINSTANCE DllHandle = LoadLibraryW(L"my.dll");
if (DllHandle == NULL)
{
ShowMessage("NULL");
return;
}
pGetCommandParameter pGetParam = (pGetCommandParameter)GetProcAddress(DllHandle, "GetCommandParameter");
if (pGetParam == NULL)
{
ShowMessage("pGetParam is NULL");
return;
}
ShowMessage(pGetParam());
Now the sharing works fine as long as multiple instances of that same Form1.exe are instantiated. Put the Button2 code in a second application, say Form2.exe and click the button to retrieve the value of lpsCommandParameter and you'll get a blank. I instantiated 4 instances of Form1.exe and the value of lpsCommandParameter from the DLL is returned fine but I keep getting blanks from a different EXE. I want this data to be visible among different EXEs as my project depends on shared data and I don't want to write anything on disk so I really want do this via data sharing in DLLs.
|
|
|
|
|
I think I might have found out what's going on. The above code works fine with an integer. According to MSDN:
Each process gets its own address space. It is very important that pointers are never stored in a variable contained in a shared data segment. A pointer might be perfectly valid in one application but not in another.
And when you think of it, LPSTR is an array of chars which *is* a pointer. I've tried the above example also with a char * (before I read this) and still made no difference as well as a std:string. All I want to really share is a bunch of chars.
Update: I found more clarification here: http://sites.google.com/site/jozsefbekes/Home/windows-programming/shared-data-segment-in-a-dll[^]
You can only have fixed size data here (no dynamic arrays or CString)
You have to initialize all data otherwise it won't be shared (Of course it makes no sense to put pointers here as the address would be valid in one process only)
So to share a string, you can create a char[] array and initialize it and then just store the value in it.
modified 7-Jan-12 16:54pm.
|
|
|
|
|
Hey everyone,
I am having difficulties in setting values to global variables in a DLL module. I am using (learning) Visual C++ 2010 Express. I am not exactly sure what I am doing wrong as this works fine with BCB. I have some DLL code written in BCB that I want ported to VC++.
In DLL source code I have this:
__declspec(dllexport) int MyInt = 100;
extern "C"
{
__declspec(dllexport) void SetMyInt(int NewValue)
{
MyInt = NewValue;
}
__declspec(dllexport) int GetMyInt()
{
return MyInt;
}
}
In main file:
Button 1 click:
typedef void (*pSetMyInt)(int Value);
HINSTANCE DllHandle = LoadLibraryW(L"file.dll");
if (DllHandle == NULL)
{
ShowMessage("Handle is NULL");
return;
}
pSetMyInt pSetInt = (pSetMyInt)GetProcAddress(DllHandle, "SetMyInt");
if (pSetInt == NULL)
{
ShowMessage("pSetInt is NULL");
return;
}
pSetInt(89);
FreeLibrary(DllHandle);
Button 2 Click:
typedef int (*pGetMyInt)();
HINSTANCE DllHandle = LoadLibraryW(L"file.dll");
if (DllHandle == NULL)
{
ShowMessage("NULL");
return;
}
pGetMyInt pGetInt = (pGetMyInt)GetProcAddress(DllHandle, "GetMyInt");
if (pGetInt == NULL)
{
ShowMessage("pGetInt is NULL");
return;
}
int Value = pGetInt();
FreeLibrary(DllHandle);
No matter what I do, the internal variable in the DLL module never gets set. It remains to the default value initialized on the top of my DLL file. This is so simple, how can it not work? I must be doing something wrong.
|
|
|
|
|
It is working as expected.
Here is what that is happening.
When button 1 is clicked, the DLL is loaded into memory and the value of MyInt which is 100 is loaded into memory.
After that the value of MyInt is changed in memory to 89 .
Then when FreeLibrary is called, the DLL and all memory used by it (including MyInt ) is unloaded from memory.
At this point, the value 89 that you set is lost.
Now when button 2 is clicked, the DLL is freshly loaded into memory along with the value 100 that belongs to MyInt .
So when you read the value of MyInt , it is 100 as expected.
To get what you're trying to do here are the steps -
Call LoadLibrary and GetProcAddress in some initialization routine before the button click event handlers are invoked.
In the button 1 click routine simply call SetMyInt .
In the button 2 click routine simply call GetMyInt .
You can call FreeLibrary in a separate cleanup routine that must be invoked only at the end.
|
|
|
|
|
Oh yes...Of course...Thank you! Yes, it makes perfect sense. It works as expected and yes commenting that line out does work and I will indeed create a separate routine that cleans up an array of handles. What was I thinking? I feel so embarrassed.
|
|
|
|
|
Hey friend, I want to ask, how to make setup from project VC6, like package and deployment wizard in VB. because I want use my project in the other PC without instal VC6. Thank you...
|
|
|
|
|