 |
|
|
 |
|
 |
John,
I don't know if I will actually be using your code, but I appreciate the research you put into this article - I wasn't aware of the changes that you have documented.
Best wishes,
Hans
|
|
|
|
 |
|
 |
Thanks John. As usual, very informative.
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
|
|
|
|
 |
|
 |
I spend a couple of hours documenting something I discovered that is NOT covered anywhere else on the web FOR YOUR BENEFIT, and some of you people insist on playing voting games. You're acting beyond puerile.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
 |
|
 |
I am sorry but if the code was correct I would not have voted 1.
|
|
|
|
 |
|
 |
Technically, this type of article is somewhat already documented. I wrote an article dealing with some aspects of system menus and I am receiving similar voting results. This may just not be an important and very useful topic in general (not saying this just about your aticle, but mine as well).
And, with a quick search at the site: searching for system menu. My article was the first result(Add Transparent Menus and XP Titlebar Buttons to your application[^]) and just below it is a good article as well:http://www.codeproject.com/dotnet/CustomWinFormSysMenu.asp[^]
Regards,
Thomas Stockwell
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Visit my homepage Oracle Studios[ ^]
|
|
|
|
 |
|
 |
This article is more about the VS2005-specific changes. When I did the same code in VC6, I didn't have the issues I had here.
Besides, Winforms isn't MFC. This is a MFC article.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
 |
|
 |
For my own articles, whenever I get a comment that I consider unfair or posted by a dips**t, I try to wait one day before responding. That way, there's a better chance that I will be responding with my brain, instead of my [insert body part].
Best wishes,
Hans
|
|
|
|
 |
|
 |
First of all system messages originate at the Operating System Level and not MFC or VS 2005. Next, you are trying to handle all documented system messages and delegating them to CFrameWnd::OnSysCommand. The CFrameWnd::OnSysCommand delegates it to DefWindowProc which then handles the system messages like SC_MINIMIZE etc.
What happens if a new system message gets defined by OS or a Service Pack? You have to add another line to your switch case statement. If you fail to do that the message wil be eaten and DefWindowProc will not get a chance to process it.
Here is the corrected version of the code:
switch (nID)
{
case ID_SHOW_MESSAGE1 :
case ID_SHOW_MESSAGE2 :
PostMessage(WM_COMMAND, nID, 0);
break;
default:
CFrameWnd::OnSysCommand(nID, lParam);
break;
}
|
|
|
|
 |
|
 |
If you don't pass every system message to the base class, they won't get handled by the program. If you want proof, try commenting out the two case statements I had to add to get the thing to work right.
As I stated in m y article, the SC_ messages I *do* handle were the only ones listed in MSDN, therefore, the others are commented out. I don't know if they're still handled because MSDN documentation SUCKS, and everybody knows it.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
 |
|
 |
Yes! That's why I rewrote your code like this:
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
switch (nID)
{
case ID_SHOW_MESSAGE1 :
case ID_SHOW_MESSAGE2 :
PostMessage(WM_COMMAND, nID, 0);
break;
default:
CFrameWnd::OnSysCommand(nID, lParam);
break;
}
}
BTW Your code does not work on Vista.
Another point to note here is that IDs should be in the range of system commands ids.
|
|
|
|
 |
|
 |
The REASON I wrote that the way I did is so that I could actually intercept those commands in the future and add my own processing before passing the message on. So, not that you've been a smartass once today, are you going to go back to thinking before you post?
Rama Krishna Vavilala wrote: BTW Your code does not work on Vista.
That's because I didn't write it on Vista. Look at the top of the article - it says Windows XP.
Stop being a dipshit.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
 |
|
 |
John Simmons / outlaw programmer wrote: Look at the top of the article - it says Windows XP.
Actually it says this :-
C++
Windows
Win32, VS, MFC
Dev
It doesn't specifically say XP anywhere.
|
|
|
|
 |
|
 |
That's a site bug, and you can't blame that on me.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
 |
|
 |
John, it would be better if you made sure you sent all messages to the base class and to do that you should follow Rama's advice. You can still catch the messages you want plus add code to notify you of any new ones if you feel the need.
switch (nID)
{
case ID_SHOW_MESSAGE1 :
case ID_SHOW_MESSAGE2 :
PostMessage(WM_COMMAND, nID, 0);
break;
case SC_CLOSE:
case SC_HOTKEY:
case SC_HSCROLL:
case SC_KEYMENU:
case SC_MAXIMIZE:
case SC_MINIMIZE:
case SC_MOUSEMENU:
case SC_MOVE:
case SC_NEXTWINDOW:
case SC_PREVWINDOW:
case SC_RESTORE:
case SC_SCREENSAVE:
case SC_SIZE:
case SC_TASKLIST:
case SC_VSCROLL:
case 61587: // show the system menu
case 61443: // allow window resizing by click/dragging the main window borders
/*
// no longer supported in VS2005/MFC8?
case SC_ARRANGE:
#if(WINVER >= 0x0400)
case SC_DEFAULT:
case SC_MONITORPOWER:
case SC_CONTEXTHELP:
case SC_SEPARATOR:
#endif
*/
CFrameWnd::OnSysCommand(nID, lParam);
break;
default:
// add some logging or something to catch new messages here
CFrameWnd::OnSysCommand(nID, lParam);
break;
}
Yeah, MS documentation blows, but this is just good coding practice. Your omission may break future windows updates.
BTW, you don't deserve a 1 vote for the article unless you refuse to fix this. I'll withhold my vote until you decide what to do.
"Acceptance without proof is the fundamental characteristic of Western religion, rejection without proof is the fundamental characteristic of Western science." - Gary Zukav |
|
|
|
 |
|
 |
Thanks, Jason, I fix this in downloaded code.
|
|
|
|
 |
|
 |
John Simmons / outlaw programmer wrote: Rama Krishna Vavilala wrote:
BTW Your code does not work on Vista.
That's because I didn't write it on Vista.
Ummm, I just ran it under Vista and had no problems with it
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
 |
|
|
 |
|
 |
John Simmons / outlaw programmer wrote: I still haven't tried running the code under Vista.
Well, if you ever do, it works fine with Vista Ultimate 32 Bit
"The clue train passed his station without stopping." - John Simmons / outlaw programmer
"Real programmers just throw a bunch of 1s and 0s at the computer to see what sticks" - Pete O'Hanlon
"Not only do you continue to babble nonsense, you can't even correctly remember the nonsense you babbled just minutes ago." - Rob Graham
|
|
|
|
 |
|
 |
Here is the code generated by MFC ialog wizard:
void CTestDialogDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
|
|
|
|
 |
|
 |
Seriously, how can you defend that? The documentation that sucks plainly states:
"An application can carry out any system command at any time by passing a WM_SYSCOMMAND message
to DefWindowProc. Any WM_SYSCOMMAND messages not handled by the application must be passed to
DefWindowProc. Any command values added by an application must be processed by the application
and cannot be passed to DefWindowProc."
You haven't done this.
If you haven't followed the documentation, how can you expect it to work?
When you posted on the C++ board about this, my first response was "Are you calling the base
class OnSysCommand()?". You said you were. Were you really using code like above (before the
"fix" was made)?
Mark
|
|
|
|
 |
|
 |
Rama Krishna Vavilala wrote: What happens if a new system message gets defined by OS or a Service Pack? You have to add another line to your switch case statement. If you fail to do that the message wil be eaten and DefWindowProc will not get a chance to process it.
Not to mention any other undocumented messages there might be.
|
|
|
|
 |
|
 |
And if I hadn't done it the way I did, we wouldn't know about the un-defined messages, now would we?
Stop being a dipshit, Nish.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
 |
|
 |
And if I hadn't done it the way I did, we wouldn't know about the un-defined messages, now would we?
But if you had done it right in the first place you wouldn't have to worry about the undefined messages. What's the point of "knowing" them? Who cares? Just pass it on.
Besides, you really still don't know about the undefined messages unless you happen to catch them while debugging. You're just ignoring them. If you want to know about them, have some sort of logging in the default of the switch, but still pass the commands on instead of eating them.
Vote withheld
|
|
|
|
 |
|
|
 |