|
I would strongly recommend a look at Bruno Podetti's NewMenu article classes. It is well written,
had a *lot* of work in it (including a smidgeon by me), and I've used it to great effect in my
own projects.
Owner Drawn Menu with Icons, Titles and Shading [^]
It has a choice of a variety of styles, including menu shadows, and all that.
Iain
|
|
|
|
|
Thank you very much !!! I will check the article!
Best regards
Tabor25
|
|
|
|
|
Here's the problem:
I have a memory DC that I create and keep around for the duration of the app. The mapping mode for this DC is setup once, and then never again. However there are times during the life of the app that I need to work in the default mapping mode (MM_TEXT). Instead of saving the context of the DC, setting up the default mapping mode and then restoring the DC to it's previous state, I thought it would be great if I could have two DC's that refer to the same 'surface' but that have different mapping modes. I know this is possible with a DC that references an actual output device such as the screen, but seems to be impossible with a memory DC. A second option I thought of would be to create a bitmap and select it into both DC's, then all drawing operations on any of the two DC's would go to the same bitmap/surface. Alas, the docs say a bitmap can only be selected into a single mem DC at any one time.
A third option I am considering, but haven't tried yet, nor do I know if it will work, is to create two DIB sections, one for each DC, with a common file mapping object and select the two bitmaps into their DC's respectively.
Any ideas on solving this problem would be greatly appreciated.
|
|
|
|
|
I developed a simple program.in that when i add an entry it stores data in the .dat file format.the file stores data perfectly in the vc++ environment.but when i link the exe file by the installer program to the start menu the .dat file not stores data properly.sometimes stores junk data,sometimes overwrite data etc.So i am having a problem in storing of data when i run the program outside vc++ environment.
|
|
|
|
|
may be some unexception problem,can you write your code for file handlling here,so other good programer can review it.
-----------------------------
"I Think It Will Help"
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
|
|
|
|
|
Can you compile the program in debug mode and add ASSERT() statements? You might also want to add try /catch blocks to see if any exceptions are being thrown.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
Hi CPians,
I have a problem with the following : I have a menu with two items, the second one being ID_OPEN_NORMAL.
I basically would like to change the item string it at runtime, which I do as follows:
CPoint point;
::GetCursorPos(&point);
CMenu menu;
DWORD dwSelectionMade;
VERIFY(menu.LoadMenu(IDR_MENU1) );
CMenu *pmenuPopup = menu.GetSubMenu(0);
ASSERT(pmenuPopup != NULL);
CString menustring;
CString str="Hello World";
if (!str.IsEmpty())
{
menustring = "Open "+str;
pmenuPopup->ModifyMenu(ID_OPEN_NORMAL,MF_BYCOMMAND,MF_STRING,menustring);
}
else
{
pmenuPopup->RemoveMenu(ID_OPEN_NORMAL,MF_BYCOMMAND);
}
dwSelectionMade = pmenuPopup->TrackPopupMenu( (TPM_LEFTALIGN|TPM_LEFTBUTTON|
TPM_NONOTIFY|TPM_RETURNCMD),
point.x, point.y, this
);
pmenuPopup->DestroyMenu();
The menu appears and the modified item string shows "Open Hello" as expected. However, dwSelectionMade contains 0 (instead of ID_OPEN_NORMAL) when I select the "Open Hello" item (so I cannot track the user's choice correctly afterwards) as if the user did not select any menu item.
It works OK for the first item, which I do not change dynamically (e.g. dwSlectionMade does contain the ID of the selected item).
Can anyone point out what I am doing wrong ?
Thanks,
~RaGE();
|
|
|
|
|
While I'm on the forum asking questions, let me contribute...
TrackPopupMenu doesn't return the selection made, it only returns whether it was successfull or not. You actually get sent a message telling you what the user selected. This means you will have to install a command handler for that particular menu ID. which will put the following in your header file:
afx_msg void OnOpenNormal(void);
The following in your implementation file
BEGIN_MESSAGE_MAP(YourWindowClass, TheBaseWindowClass)
....
....
ON_COMMAND(ID_OPEN_NORMAL,OnOpenNormal)
...
END_MESSAGE_MAP()
And the handler code
void YourWindowClass::OnOpenNormal(void)<br />
{<br />
<br />
}
|
|
|
|
|
I would completely agree with this, but ... if I do not modify the string with ModifyMenu , surprisingly and on contrary to what is said in the MSDN, TrackPopupMenu does return the made selection ! That's also ratehr obscure to me ...
~RaGE();
|
|
|
|
|
Two things:
Firstly, you are right that TrackPopupMenu returns the menu ID you have picked, as
you are using thre TPM_NONOTIFY|TPM_RETURNCMD flags.
Secondly, you have the third parameter of ModifyMenu wrong. This is from MSDN:
CMenu::ModifyMenu
BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL );
You should have
pmenuPopup->ModifyMenu(ID_OPEN_NORMAL,MF_BYCOMMAND | MF_STRING, ID_OPEN_NORMAL, menustring);
instead of your version.
As the docs say, this is a deprecated api function. You might want to look at Get/SetMenuItemInfo,
though be aware that MENUITEMINFO changed size after NT4. See a later forum post for more info.
Hopefully this helps!
Iain.
|
|
|
|
|
Thanks Iain,
I have found this meanwhile myself, but thanks for pointing this out. As you said, I blamed TrackPopupMenu for acting badly while my parameters in ModifyMenu were wrong.
Thanks a lot.
Btw, I like ModifyMenu because I find it very straight forward, whereas SetMenuItemInfo , though more complete, requires using a structure, aso ...
~RaGE();
|
|
|
|
|
The OnTimer() function , which is called after a timer is created by SetTimer (),is processed when there is no other message to be processed. I wanted to make a second by second update to my program but it fails as when the user clicks very fast or if many messages are sent by the user or the program.
How can make a second by second update (a timer that will always get exact count)or ; make the WM_TIMER message to have higher priority
Thanks
|
|
|
|
|
leyusha wrote:
How can make a second by second update (a timer that will always get exact count)or ; make the WM_TIMER message to have higher priority
forget it. Windows is not a Real-Time Operating System, that means that the kernel will always have priority upon the user events. this way, for an event to be treated, it will have to wait for the end of the event that is currently in treatment, or it will have to wait that the kernel finishes its task...
if you want this, sorry but, change your OS...
TOXCCT >>> GEII power
|
|
|
|
|
leyusha wrote:
The OnTimer() function , which is called after a timer is created by SetTimer (),is processed when there is no other message to be processed. I wanted to make a second by second update to my program but it fails as when the user clicks very fast or if many messages are sent by the user or the program.
How can make a second by second update (a timer that will always get exact count)or ; make the WM_TIMER message to have higher priority
You didn't mention how exact the count needs to be, so I should mention that you aren't ever going to get milisecond accuracy. However, it's quite possible that you can display an update so that the user sees something new about every second.
Another issue it that paint messages have an even lower priority than timer messages. If your program has long periods in which no timer messages get through, then no paint messages will get through either. This can lead to things like message boxes not being displayed, leaving the user wondering why your program has stoped responding. Because of this, the best solution is probably just to make your message handling efficient enough that timer messages can get through in a reasonable amount of time.
That being said, you can effectively make higher priority timer messages by having a background thread wait on timer messages or a waitable timer object, and having the thread send a WM_COMMAND or a custom message that will have normal priority. If the background thread doesn't do anything else, you can safely raise the thread's priority to get a bit more accuracy.
Nathan Holt
|
|
|
|
|
Nathan Holt at CCEI wrote:
You didn't mention how exact the count needs to be
was i the only one to see that he wanted a timeout of one second ( 1 s ) ?
TOXCCT >>> GEII power
|
|
|
|
|
toxcct wrote:
was i the only one to see that he wanted a timeout of one second ( 1 s ) ?
Windows can usually syncronize things to within a second. Audio and video players wouldn't be possible if that wasn't the case. If the OP can accept updates a quarter of a second late, he can probably get what he wants. There are sometimes high load situations that can delay things further, but users can often just avoid running too many programs. It works with things like Windows Media Player.
Nathan Holt
|
|
|
|
|
As the other reply states, you can't boost the priority of WM_TIMER. It isn't a real message in the
message queue, but is synthesised by windows.
But you can be cunning...
You can override CWinApp::Run and change the message loop to time out once a second, which is lot of
work.
Or...
Create a thread which does nothing much beyond:
DWORD MyTickingThread (LPVOID lpParameter)
{
HWND hWndNotify = (HWND) lpParameter;
while (g_CarryOnTicking)
{
::Sleep (1000);
PostMessage (hWnd, g_TickMessage, 0, 0);
}
return 0;
}
Of course, this is a very primitive example, but hopefully you get the idea.
You may want a more sophisticated (CreateEvent, etc) method of signalling to / from
the thread, and so on.
This still won't be exactly on the second, as windows is not a RTOS, but it will be
better WM_TIMER.
Iain.
|
|
|
|
|
I have a similar problem with the applications that I need to write, and as I think someone previously has said Windows is not real time and you cannot perform tasks at precise times.
However if like me you are stuck with Windows the following might be of interest. I have found that I can get a close approximation by putting the time critical event in a seperate thread, keep it as small and as fast as possible and give it a high priority. My code takes samples from the RS232 port at 100ms intervals and is reasonably accurate.
I have added a check to ensure that if there is a large error in the timing the user is told and they can shut down some apps or get a faster machine!
Hope that helps,
Ali
|
|
|
|
|
Hey guys thnks for the replies, i think i will go with the thread thing
Thanks a Lot but i was just wondering which os are real time systems ?
|
|
|
|
|
Also, I have read in Game Development books to use QueryPerformanceCounter() and GetTickCount() because they're more accurate.
[insert witty comment here]
bdiamond
|
|
|
|
|
I developed a small project in vc++. What happens it runs perfectly in vc++ 6.0 environment,but didn't run properly outside it as i link it to the start menu.
|
|
|
|
|
could you in brief detail the folder where you exe is located, and the files it needs (their location too). Explain also what you exactly do into the start menu...
thx
TOXCCT >>> GEII power
|
|
|
|
|
ya hi toxcct.The exe is in the debug folder.when i put the .exe & .dat files in the windows start menu(Windows/startmenu/addressbook.exe).The program's exe not stores data properly as i wrote some times junk,sometimes overwrite the prev. data.It not stores the data perfectly as it stores under vc++ environment.help me.
My application is a simple address book app.. where records stores in the .dat file.
|
|
|
|
|
See here.
"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen
|
|
|
|
|
don't put your binary direclty into the start menu. let it in a folder (in program files for example), and just add in the start menu a shortcut (.lnk) to your .exe.
TOXCCT >>> GEII power
|
|
|
|