- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I run my program within Microsoft Visual Studio it works fine but when I run the compiled version it hangs.
It is difficult to track where the problem is occuring.
I have been opening & writing and closing a text file so I can create a log of where I have been.
I think I have tracked where the problem is occurring, it's in a routine that gets mouse key presses and keyboard characters.
Do you have any suggestions on to how I can add more debugging or run it in a mode where I can get more debug.
The program worked in Windows XP, the problem occurs when running in Windows 7.
Thanks
It is difficult to track where the problem is occuring.
I have been opening & writing and closing a text file so I can create a log of where I have been.
I think I have tracked where the problem is occurring, it's in a routine that gets mouse key presses and keyboard characters.
Do you have any suggestions on to how I can add more debugging or run it in a mode where I can get more debug.
The program worked in Windows XP, the problem occurs when running in Windows 7.
Thanks
Link Copied
- « Previous
-
- 1
- 2
- Next »
30 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian,
Thanks for your comments.
This is program I inhereted from the previous developer and some of the fundimental message handling I don't understand. I have been adding functionality but never tinkered with how the basics work.
Your suggestion on the Get/Translate/Dispatch message loop may be easier to implement. Is there an example somewhere of how it works so I can give it a try?
David
Thanks for your comments.
This is program I inhereted from the previous developer and some of the fundimental message handling I don't understand. I have been adding functionality but never tinkered with how the basics work.
Your suggestion on the Get/Translate/Dispatch message loop may be easier to implement. Is there an example somewhere of how it works so I can give it a try?
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know of any example. The concept is that you would have another message loop similar to your main loop (around line 177 of Grade.f90) that filtered out messages of interest and passed everything else on. Some sort of trigger (mouse button up, keypress) terminates this second loop and it passes coordinates or whatever back to the calling procedure.
As a sketch (this won't compile, it isn't complete, I'm not really sure what your original code was trying to achieve in the first place, etc):
[fortran] LOGICAL :: ok ! true on success, false on failure TYPE(T_MSG) :: msg TYPE(T_POINT) :: pt INTEGER(BOOL) :: bRet INTEGER(LRESULT) :: lRet !**** DO bRet = GetMessage(msg, NULL, 0, 0) IF (bRet == 0) THEN ! Post another copy of the quit message so that our "parent" loop will ! also exit. bRet = PostMessage(msg%hwnd, msg%message, msg%wParam, msg%lParam) ok = .FALSE. RETURN ELSE IF (bRet < 0) THEN ! Some sort of error. ok = .FALSE. RETURN END IF bRet = TranslateMessage(msg) IF (msg%hwnd /= hWndMain) THEN lRet = DispatchMessage(msg) ELSE ! Filter out messages of interest, process them specially, pass ! everything else on. SELECT CASE(msg%message) CASE (WM_CHAR) SELECT CASE(wParam) ! Character code CASE (VK_ESC) ok = .FALSE. RETURN CASE (...other keys of interest...) .... CASE DEFAULT ! Ignore keypress END SELECT CASE (WM_MOUSEMOVE) ...draw cursor?... CASE (WM_LBUTTONUP) ...set x, y, ok = .TRUE. return? CASE (other messages of interest) ... CASE DEFAULT ! mesage that we dont want special processing of... lRet = DispatchMessage(msg) END SELECT END IF END DO [/fortran](Your MainWndProc should be marked RECURSIVE too).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian,
Thanks for that code sample. I think I have got is working now on the 'cut down version'. I have to move onto another project for a week. I will then hope get it working in the full version.
It looks as if the peekmessage was causing the problem.
Thanks again.
David
Thanks for that code sample. I think I have got is working now on the 'cut down version'. I have to move onto another project for a week. I will then hope get it working in the full version.
It looks as if the peekmessage was causing the problem.
Thanks again.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have tried updating my full project and found there is a problem. This problem also occurs on the cut down project - I hadn't realised as the data was just small.
The grapics lines are only being drawn on the screen when you move the mouser around. If you keep the mouse still the screen is blank but as soon as I move my mouse it starts to draw, the more I move the mouse more is drawn.
Can you suggest where the problem occurs.
I could submit the updated code.
Thanks.
The grapics lines are only being drawn on the screen when you move the mouser around. If you keep the mouse still the screen is blank but as soon as I move my mouse it starts to draw, the more I move the mouse more is drawn.
Can you suggest where the problem occurs.
I could submit the updated code.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suspect that there's a problem with the window invalidation/repainting logic. There are a couple of ways of setting things up and I don't know what your application implements.
(One that is typical is that all drawing on the window is only ever done in response to a WM_PAINT message. When events happen (such as mouse movement) that require a change in the window's visuals, the code handling those events invalidates the areas that require updating. The actual drawing happens "later" in response to the paint message (though "later" might be right away if UpdateWindow is called by the event handling procedure. Perhaps your application does something different - whatever it is you need to be able to describe it in a similar manner.)
If you post the code I'll have a look, but this is more to do with the Window's api than Intel Fortran per-se.
(One that is typical is that all drawing on the window is only ever done in response to a WM_PAINT message. When events happen (such as mouse movement) that require a change in the window's visuals, the code handling those events invalidates the areas that require updating. The actual drawing happens "later" in response to the paint message (though "later" might be right away if UpdateWindow is called by the event handling procedure. Perhaps your application does something different - whatever it is you need to be able to describe it in a similar manner.)
If you post the code I'll have a look, but this is more to do with the Window's api than Intel Fortran per-se.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian,
Thanks for your help.
Here is the project and the data. It is similar to that before.
Unzip both files. Use File Open to open the file 'Example.gbf'. The full graphics is drawn (see example.jpg). If you use the wheel mouse to zoom in or out, the graphics disappears. As you move the mouse around the graphics is drawn bit by bit.
Thanks again.
David
Thanks for your help.
Here is the project and the data. It is similar to that before.
Unzip both files. Use File Open to open the file 'Example.gbf'. The full graphics is drawn (see example.jpg). If you use the wheel mouse to zoom in or out, the graphics disappears. As you move the mouse around the graphics is drawn bit by bit.
Thanks again.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian,
Have you been able to look at my project?
I am stuck, do you have any suggestions on where I could get further help?
Thanks,
David
Have you been able to look at my project?
I am stuck, do you have any suggestions on where I could get further help?
Thanks,
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had a look when you first posted it and couldn't work out then what was going wrong. My notes from then:
Previously the subsidiary message loop/filter was discussed in the context of the application entering a selection mode - this is a quite a different context!
If the idea is to allow the user to cancel the drawing then you need to go back to the PeekMessage approach (there's no loop - just look for WM_KEYDOWN for that window alone), but if your window's client area is that complicated that the user actually has time to reach over and hit a key to cancel the drawing then your whole approach to drawing needs to be re-thought.
Anyway, a message sent to any window owned by the thread other than the main terminates this loop (there's a return on line 350), and if the message is sent to the main window then the wparam parameter appears to be interpreted as a keyboard character regardless of the type of message and every message is processed in the same way (there's no "select case (msg%message)" bit to actually filter out messages of interest, there's no handling of paint messages, no default message processing, nada).
I don't know what is supposed to be happening here (I think that's your first job - document in comments in the code what the code is trying to do (and "why" it is the way it is too)) - so I won't try and "correct" things, but...
Typically, an application responding to the scroll wheel on a mouse would determine a new scale factor for the display (if "zooming" is what the mouse wheel does in the app) and then just invalidate the relevant part of the client area of the window (often zooming requires the entire area to be redrawn). That's it.
When it feels like it (which with modern CPU's and graphics cards, etc, will be before the user's brain has realised that it has finished moving the scroll wheel) the system then sends the window procedure a WM_PAINT message for the invalidated area, and all drawing is handled there.
That pattern typically applies to every event that might require the screen to be changed - the code handling the event works out what part of the screen needs to be redrawn, invalidates it and WM_PAINT handling then does the actual drawing. Exceptions to this pattern exist (often as useful optimisations when specific parts of the screen are being updated constantly), but they require careful consideration and design.
- This code is very difficult to follow. There are cryptic variable and procedure names, a large number of global variables, a limited number of comments and too much use of unstructured execution control (goto, etc - I also think I stumbled on a computed goto at one stage, but then my head compiler ICE'd). By being difficult to follow this code would be a nightmare to maintain and difficult to debug. The code would benefit greatly from a progressive rewrite (or perhaps a total rewrite) using language features introduced with Fortran 90 and beyond.
- The application isn't calling BeginPaint/EndPaint in response to WM_PAINT messages. These API's are what Windows uses to keep track of the update region for each window, amongst other things. The application should never send WM_PAINT messages, that's a job for the system (areas that need re-painting should be invalidated - the system will then arrange for WM_PAINT to turn up in the message queue). The whole way the application handes painting is a bit bizarre - perhaps this was some way that painting could appear to be being done in the background???
- The main window message procedure needs to be recursive - many API calls result in messages being sent to the window (and hence you get an immediate call of the window proc if it is a single threaded application).
- There are code paths through the window procedure that never set the return value of the function. The return value is significant for some messages and that significance can change from windows version to version.
- There is the potential for a GDI resource leak in a few places - handles being destroyed before being selected out of a DC, etc.
Previously the subsidiary message loop/filter was discussed in the context of the application entering a selection mode - this is a quite a different context!
If the idea is to allow the user to cancel the drawing then you need to go back to the PeekMessage approach (there's no loop - just look for WM_KEYDOWN for that window alone), but if your window's client area is that complicated that the user actually has time to reach over and hit a key to cancel the drawing then your whole approach to drawing needs to be re-thought.
Anyway, a message sent to any window owned by the thread other than the main terminates this loop (there's a return on line 350), and if the message is sent to the main window then the wparam parameter appears to be interpreted as a keyboard character regardless of the type of message and every message is processed in the same way (there's no "select case (msg%message)" bit to actually filter out messages of interest, there's no handling of paint messages, no default message processing, nada).
I don't know what is supposed to be happening here (I think that's your first job - document in comments in the code what the code is trying to do (and "why" it is the way it is too)) - so I won't try and "correct" things, but...
Typically, an application responding to the scroll wheel on a mouse would determine a new scale factor for the display (if "zooming" is what the mouse wheel does in the app) and then just invalidate the relevant part of the client area of the window (often zooming requires the entire area to be redrawn). That's it.
When it feels like it (which with modern CPU's and graphics cards, etc, will be before the user's brain has realised that it has finished moving the scroll wheel) the system then sends the window procedure a WM_PAINT message for the invalidated area, and all drawing is handled there.
That pattern typically applies to every event that might require the screen to be changed - the code handling the event works out what part of the screen needs to be redrawn, invalidates it and WM_PAINT handling then does the actual drawing. Exceptions to this pattern exist (often as useful optimisations when specific parts of the screen are being updated constantly), but they require careful consideration and design.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian,
Thanks for looking at my problem. I agree it is not good programing, it was writtem about 15 years ago by a previous employee who I thought did a good job getting the windows user interface to work. As you say it's difficult to understand and I don't understand all about how it work - but it has been working and am reluctant to change fundimental parts of the software.
I have now made a few changes to the lines you suggested but am still having trouble with the graphics being drawn - I will investigate it more.
Looking back at my original problem I found http://msdn.microsoft.com/en-us/library/dd744765%28v=vs.85%29.aspx 'Preventing Hangs in Window Applications'. My hang doesn't occur when doing a long process but it gives the same effect. The solution is generally to write better code which I expect is the same as your suggestion to replace the PeekMessage statements.
David
Thanks for looking at my problem. I agree it is not good programing, it was writtem about 15 years ago by a previous employee who I thought did a good job getting the windows user interface to work. As you say it's difficult to understand and I don't understand all about how it work - but it has been working and am reluctant to change fundimental parts of the software.
I have now made a few changes to the lines you suggested but am still having trouble with the graphics being drawn - I will investigate it more.
Looking back at my original problem I found http://msdn.microsoft.com/en-us/library/dd744765%28v=vs.85%29.aspx 'Preventing Hangs in Window Applications'. My hang doesn't occur when doing a long process but it gives the same effect. The solution is generally to write better code which I expect is the same as your suggestion to replace the PeekMessage statements.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks to all those that helped with this problem - especially Ian & Steve.
I eventually got the solution - I just needed to add one line of code.
The PeekMessage commands I was using causes the message buffer to get filled and the computer cannot process them all so Window7/Vista thinks the computer has hung.
The solution is to add an other PeekMessage to flush the buffer.
bret=PeekMessage (msg,NULL,0,0,PM_NOREMOVE) ! flush messages or it thinks it has hung.
David
I eventually got the solution - I just needed to add one line of code.
The PeekMessage commands I was using causes the message buffer to get filled and the computer cannot process them all so Window7/Vista thinks the computer has hung.
The solution is to add an other PeekMessage to flush the buffer.
bret=PeekMessage (msg,NULL,0,0,PM_NOREMOVE) ! flush messages or it thinks it has hung.
David

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »