|
No issue in adding text to the status bar in general, just when moving the mouse over the dynamic menu items.
looking for the place where the mouse is handled when the menu is opened (showing).
Thanks.
Watched code never compiles.
|
|
|
|
|
Hey Max,
I invested a couple of minutes into downloading and looking at the Microsoft sample. I am assuming that you are referring to the dynamic menu being built to hold the user favorites. It looks like the author of the code sample used 0xE00 as a magic number for the beginning ID-offset of those dynamic menu items.
You stated in your post that you are already using ON_UPDATE_COMMAND_UI and that it was working for the other menu items. Therefore I would recommend that you use:
ON_UPDATE_COMMAND_UI_RANGE[^]
Since we know that the author of the code sample used the magic number 0xE00 as the starting ID... then you could do something like:
ON_UPDATE_COMMAND_UI_RANGE(0xE00,0xE00 + 0xFF, &CMainFrame::OnUpdateFavorites)
With this minor change the code sample will fire OnUpdateFavorites when the user moves the mouse over those favorites. You would also need to modify the code where the author does not set a menu ID on some of the sub menus. Either put them into the magic number range or create a new magic number range. Keep in mind that because the status bar was not created with a resource ID... it gets the default MFC id of AFX_IDW_STATUS_BAR. You could change this resource ID and obtain full control over your status bar.
Some additional off-topic comments:
The code sample is poorly written and uses a recursive function for building that menu based on a folder layout on the users hard drive. It would be possible to craft a folder layout that would cause this code sample to recursion until a stack overflow occurred. The code sample also does not handle NTFS junction points which could also be used to generate a stack overflow. If you intend to use this code in a commercial product you may want to re-design the function that builds the favorites menu. I did not perform a full code review so there may be other issues.
Best Wishes,
-David Delaune
modified 4-Jan-12 10:15am.
|
|
|
|
|
I'm not using ON_UPDATE_COMMAND_UI but CN_UPDATE_COMMAND_UI in CMainFrame::OnCmdMsg.
AFAIK, The ON_UPDATE_COMMAND_UI(_RANGE) and CN_UPDATE_COMMAND_UI will be called when the menu is created, not when the mouse moves over the different menu items
If I use the range, I still have to manage/handle each item individually to find out which one I click I selected to be able to "do" whatever I need to "do" (that is working perfectly with the code in CMainFrame::OnCmdMsg), in my case it is to open a file (
I've already fixed some of the issues that could be found in the msdn samples.
My only issue is not the adding/handling of dynamic menu items, it is only display the associated text in the statubar when the mouse moves over menu items.
Anyway, it is only a small enhancement for now.
Thanks.
Watched code never compiles.
|
|
|
|
|
Maximilien wrote: AFAIK, The ON_UPDATE_COMMAND_UI(_RANGE) and CN_UPDATE_COMMAND_UI will be called when the menu is created, not when the mouse moves over the different menu items
No, that is not correct. ON_UPDATE_COMMAND_UI and ON_UPDATE_COMMAND_UI_RANGE is called when the UI may potentially require an update. (Such as when the user moves his mouse over the menu item)
Btw... you do know that... ON_UPDATE_COMMAND_UI is a handler for CN_UPDATE_COMMAND_UI right?
#define ON_UPDATE_COMMAND_UI(id, memberFxn) \
{ WM_COMMAND, CN_UPDATE_COMMAND_UI, (WORD)id, (WORD)id, AfxSigCmdUI, \
(AFX_PMSG) \
(static_cast< void (AFX_MSG_CALL CCmdTarget::*)(CCmdUI*) > \
(memberFxn)) },
#define ON_UPDATE_COMMAND_UI_RANGE(id, idLast, memberFxn) \
{ WM_COMMAND, CN_UPDATE_COMMAND_UI, (WORD)id, (WORD)idLast, AfxSigCmdUI, \
(AFX_PMSG) \
(static_cast< void (AFX_MSG_CALL CCmdTarget::*)(CCmdUI*) > \
(memberFxn)) },
Anyway... I have shown you how you can update the status bar when the mouse moves over the menu item using ON_UPDATE_COMMAND_UI_RANGE. I tested this and it absolutely works, I can update the status bar in the MFCIE sample with the favorite URL.
I do not know if you can use CMainFrame::OnCmdMsg to recieve these messages... I have not tested it. The reason I mentioned AFX_IDW_STATUS_BAR in my previous post was to illustrate that you are essentially using the MFC status bar if you are using this default ID. MFC generally implements a message filter... ingoring messages not intended for it. This is how menu items are greyed out in MFC if they do not have a handler.
I'll do a test here in a few minutes to see if I can catch that menu ID range in CMainFrame::OnCmdMsg.
Best Wishes,
-David Delaune
[UPDATE]
Sorry about the long delay... I was briefly sidetracked.
I have confirmed that I can also catch the menu id and index inside CMainFrame::OnCmdMsg
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if(nCode == CN_UPDATE_COMMAND_UI)
{
CCmdUI *pCmdUI = reinterpret_cast<CCmdUI *>(pExtra);
if(NULL != pCmdUI)
{
TRACE2("%d : %d\n",pCmdUI->m_nID,pCmdUI->m_nIndex);
}
}
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
modified 4-Jan-12 10:58am.
|
|
|
|
|
Thanks for your time; I kind of suck this year!
Will look into it.
Max.
Watched code never compiles.
|
|
|
|
|
Maximilien wrote: Thanks for your time; I kind of suck this year!
Don't worry, we are only 4 days into the new year! I am sure that you are still recovering from the holiday. I'm still on holiday over here and enjoying my free time...
Best Wishes,
-David Delaune
|
|
|
|
|
I would like to pass a CString as a pHint parameter, in UpdateAllViews.
Since CString is not derived from CObject the following code gets rejected by compiler with the criptic error message.
CObject *pHint;
pHint = reinterpret_cast<CObject*>(strEdit);
E:\0 OpenLog\V1\TCC\TCCDoc.cpp(999) : error C2440: 'reinterpret_cast' : cannot convert from 'class CString' to 'class CObject *'
Conversion requires a constructor or user-defined-conversion operator, which can't be used by const_cast or reinterpret_cast
I am cluless as far as what kind of constructor or how to code "user-defined-conversion operator".
Help would be appreciated, as always.
Thanks
Vaclav
Dummy forgot to utilize document/view and let the view get the string from the associated document.No need to pass pHint anything.
-- modified 3-Jan-12 15:12pm.
|
|
|
|
|
Why don't you simply derive a new class (having a CString data member) from CObject and pass it to the UpdateAllViews method?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Oops, I am soo stupid, I better quit for a while.
Why don't I let the view get the string from the associated document which posted the UpdateAllViews instead. I know, the purists will argue that document/view architecture supposed to work the other way - from view to document.
But this should work for me.
|
|
|
|
|
Good one, I like your KISS approach.
Thanks
|
|
|
|
|
agreed, like your KISS approach!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
Hi all, how can I check if window is hidden by another window?
I tried IsWindowVisible but doesn't work.
|
|
|
|
|
Take a look at these functions:
GetNextWindow() , and GetForegroundWindow()
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
|
Do you really need to check if it's visible? ...If you need it to be in the forefront, why not just bring it to the front (use CWnd::SetWindowPos() )?
|
|
|
|
|
Hey,
In my App i have one thread that grabs frames from a camera and paste them on the client window.
The client window belongs to the main thread of the App so when i try to resize it my App crushes.
I think it happens because the window is a mutual resource of the threads so what happens is that both access him at the same time.
how can i solve my problem?
Thanks
|
|
|
|
|
Hi,
Your question is not very well formed. You should consider revising it and give us an error code, and any other relevant information.
columbos14927 wrote: In my App i have one thread that grabs frames from a camera and paste them on the client window.
Are you saying that you use Clipboard Operations[^] to paste an image? Are you sure about this?
columbos14927 wrote: The client window belongs to the main thread of the App so when i try to resize it my App crushes.
I certainly hope your monitors are not being crushed as that would get expensive very fast. I believe you mean crashes? If so... then you should have received an error code. When you ask for help from other software engineers... please give detailed information including any error code.
columbos14927 wrote: I think it happens because the window is a mutual resource of the threads so what happens is that both access him at the same time.
Windows belong to a single thread. However if you attempt to access resources that belong to that thread from other threads... Yes, this can cause problems.
columbos14927 wrote: how can i solve my problem?
I have no idea. I have no error code, no source code and no description of the application architecture.
Best Wishes,
-David Delaune
|
|
|
|
|
Hey,
1.The painting on the window is done by some function that is provided by frame grabber manufactorer.
I pass to this function the the handle to my window and the frame and then i call the "RedrawWindow" function.
2.When i resize the window the App freezes and not responding to anything there are no error codes.
Hope its more clear now...
|
|
|
|
|
Hi,
columbos14927 wrote: 1.The painting on the window is done by some function that is provided by frame grabber manufactorer.
Have you considered contacting the manufacturer?
columbos14927 wrote: 2.When i resize the window the App freezes and not responding to anything there are no error codes.
If you want to be a good software engineer then you will need to learn how to use your debugger.
When your application freezes:
1.) Execute a Debug build of your application from Visual Studio with debugger attached.
2.) Inside your Visual Studio you need to do a 'Break All'
3.) In Visual Studio make sure that Debug->Windows->Thread is visible. If you are a keyboard kind of guy this would be: CTRL+ALT+H
4.) In Visual Studio make sure that Debug->Windows->Callstack is visible. If you are a keyboard kind of guy this would be: CTRL+7
5.) Each thread is listed in the window along with the top of the callstack.
6.) You can select a thread in the Visual Studio debugger... and the 'CallStack' window will show the callstack associated with that thread.
Now you will be able to find what is causing the freeze.
Sometimes I find that WinDbg[^] is more powerful. If you want to use this then you would:
1.) Compile a Debug version of your application with Visual Studio.
2.) Download and install Debugging Tools for Windows[^]
3.) Launch your application from WinDbg or conversely... attach to the running instance.
4.) Wait for the freeze, or invoke it.
5.) When it freezes... Choose Debug->Break from the menu or from keyboard CTRL+BREAK
6.) Issue the command: !analyze -v -hang to have WinDbg analyze any hangs.
7.) Inspect the callstack of all threads and look for possible causes to the hang: ~*kv 250
8.) Another useful command is: !runaway[^] for having a look at thread times. Sometimes a hanging thread is spinning in an infinite loop and you can see which thread is hung... by observing that its consuming all of the thread times.
9.) If you still have not found it yet... it could be the main thread in a wait state... infinitely waiting to obtain a critical section or mutex... you can issue an !ntsdexts.locks[^] to look for critical sections and waiting threads.
If you are using WinDbg to debug a 32 bit executable under WOW64 then you might need to issue: .load wow64exts; .effmach x86
Someone should probably write and article or Tip/Trick about this.
Best Wishes,
-David Delaune
|
|
|
|
|
Client area painting must occur in the main Windows thread. The problem is that the thread grabbing the frames is not the main Windows thread. So while it's drawing to the client area, any old windows message might come along and cause a crash as the two threads bump into each other. This is especially true when resizing - there are lots of "PAINT" messages hitting the dialog, and there's a good chance that PAINT handling is happening at the same time your other thread is drawing to the client area. Result is a crash.
The solution is to have the main windows thread do the drawing. So you'll need a way to move the frames from the grabber thread to the windows thread, and signal your dialog that it's time to draw a new frame.
You could try using a custom message, e.g. WM_USER+<n> ( see here: http://www.ucancode.net/Visual_C_MFC_Example/RegisterWindowMessage-WM_USER--VC-Example.htm[^] ). You can allocate a buffer to hold the frame and pass the pointer to that buffer as the LPARAM. The frame-grabber thread then just needs to PostMessage(...) to the Dialog.
On the Dialog side, add the handler for the WM_USER+<n> message to draw the image pointed to by LPARAM. Don't forget to deallocate that buffer when done!
This is just one example for moving information from some "outside" thread to the main windows thread. You can probably find many others.
- Bob
Bob Ciora
|
|
|
|
|
|
Another way to handle this may be to pause your camera app during dialog paint and resize functions.
Assuming the API allows this.
|
|
|
|
|
Is there a function for determining the size of a DLL image as it is loaded into the process address space?
How do we determine the base address of a loaded DLL?
Also, is there some way to tell the system to load a DLL at a base address that I specify, regardless of the image's preferred base address?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
There's some good info on related topic in here: Hooks and DLLs[^]
"Real men drive manual transmission" - Rajesh.
|
|
|
|
|
Thanks. I'll check that out.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|