- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
コピーされたリンク
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Mike, to get the screen updating while rtn_designtofmis is being executed, you have to do one of two things:
1) Insert a [do while PeekMessage...] loop into rtn_designtofmis code to be executed "frequently enough".
2) Launch rtn_designtofmis in a separate thread (CreateThread), then wait for it using MsgWaitForMultipleObjects as before. That requires no changes in dll source code. However, to pass arguments to the ThreadProc (which may have only one argument lpParameter), either make them global, or, better, pack them into a TYPE and pass its address:
type t_rtn_designparams
character(7) dbase
integer hProgress
...
end type t_rtn_designparams
type(t_rtn_designparams) rtnd
...
rtnd = t_rtn_designparams(dbase, hProgress)...
handles(1) = CreateThread(NULL, 0, LOC(ExecRtn), LOC(rtnd), 0, &
LOC(idThread))
do while(.true.)
iret = MsgWaitForMultipleObjects(...
...
end do
iret = CloseHandle(handles(1))
integer function ExecRtn(rtnd)
!DEC$ATTRIBUTES STDCALL:: ExecRtn
!DEC$ATTRIBUTES REFERENCE:: rtnd
type(t_rtn_designparams) rtnd
LoadLibrary(...
call rtn_designparams(rtnd%dbase, rtnd%)
ExecRtn = 0
end function ExecRtn
Jugoslav
P.S.1: You should call CloseHandle for PI%hProcess and PI%hThread when you're done with Excel.
P.S.2: After re-reading the docs, you need a do while (PeekMessage(...)) instead of if (PeekMessage(...)). As it is now, messages could be "eaten".
P.S.3: You're better off using ShellExecuteEx than CreateProcess if you want portability. On my computer, Excel.exe is not in PATH, so CreateProcess fails.
* (Actually, message loops operate on per-thread basis. However, even if you program a multi-threaded application, it's a good practice having only one GUI thread, i.e. with message loops and creation of windows. Doing otherwise is a good way to shoot yourself in the foot.)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Michael,
The answer to your problem is to replace the 'pointless message box call'
with a WM_ERASEBKGND message to the progress bar:
!iret = MessageBox(ghwndMain,'Click OK to continue'C,'Pointless message'C, MB_OK)
iret=SendDlgItemMessage(Dlg%hWnd, IDC_PROGRESS, WM_ERASEBKGND,0,0)
please do not ask me why, it is a mystery!
regards
Tony Richards
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
OK. Here is what happens on my system (CVF 6.6c, windows XP pro)...
With your unmodified code (except the full path to EXCEL is edited into the CreateProcess call), I press the 'Apply' dialog button and EXCEL starts.
IfI then press your EXCEL 'OK' BEFORE more than six or so seconds elapse, you get your number crunching and the progress bar updates ok!
I have repeated this over and over, it works every time, so long as you press 'OK' before a certain elapsed time.
If you wait any longer, and carefully watch your dialog window, you will see it
'flash' as itappears to beredrawn, but I find a small portion of it previously covered by my EXCEL window remains unredrawn and, guess what, when you then press your EXCEL 'OK' button, number crunching occurs but the progress bar FAIULS TO UPDATE. So it is partly a timing problem (it fails only after a certain elapsed time) and partly a consequence of what happens to your dialog window in that important flash when it appears to be updated.
Hope this helps!
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Might it therefore be worth trying a modification to your numbercrunching code that sends the PBM_SETPOS messages to the progress bar to preced/follow it with a WM_PAINT , 0,0 message each time and see what happens?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Hi Guys,
Thanks for all your help and many suggestions. I really have got the problem fixed this time.
Anthony, I tried many of your suggestions (one or two before you'd made them) and found the same type of "weird" inconsistent behaviour. I also found that timing was very important, which is why in an earlier post I stated that the problem was solved. It turned out that it was only solved when I went through the program quickly - a totally unrealistic situation.
Jugoslav's solution is the one that works - I am now running the number cruncher DLL in a separate thread and it works like a charm every time. I've learnt heaps throughout this process and now understand a little about separate threads, etc, where I knew nothing about them before.
Thanks again to everyone.
Mike
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Anthony,
I'm using Windows XP and CVF 6.6. I guess I could (and perhaps should) have spent a lot more time investigating such subtleties but I'm under some pressure just to get the thing working so that I can move on to other things. Now that I've got the basic technique I have to extend and apply it to a number of similar cases, so I've still got lots to do.
Many thanks again,
Mike
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
My point is, SendMessage(WM_ERASEBKGND) and SendMessage(WM_PAINT) are undocumented ways to achieve updating; as you discovered by "reverse-engineering", they're not reliable. Actually, I've never seen anywhere that direct sending of these two messages is a recommended way to do something; instead, you're supposed to pump these redrawing messages via a message loop of some kind.
Jugoslav
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
True, but that's usually not the problem (unless there's a very heavy message traffic accompanied by long processing code). However, in Mike's case, even if the message queue were empty otherwise, WM_PAINT could not be processed because no message can be processed while calculation is running. There's only one thread, remember.
I have seen statements in the same articles that say that UpDateWindow is the way to go if you want immediate response.
I tried InvalidateRect+UpdateWindow instead of PeekMessage loop in another example of mine (inspired by this very thread) and it does work, but it's not good enough. While user sits still, the progress bar gets updated, but e.g. Alt+Tab does not work anymore as expected -- the WM_ACTIVATE(APP) messages are not handled so the window can't put itself foreground until calculation is finished.
Jugoslav
Message Edited by JugoslavDujic on 10-07-2005 10:54 AM
