Announcement

Collapse
No announcement yet.

DDT, refresh controls.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Semen Matusovski
    replied
    Lance --
    Really I offered something like this (looks that "others" means I).
    What's is not according PB rules ?

    Code:
     
        #Compile Exe
        #Include "WIN32API.INC"
        #Include "COMMCTRL.INC"
    
        %ID_ProgressBar = 501
        Global hProg As Long, hPrDlg As Long
        Global StopDn%, Redrawn As Long
    
        Sub StopModal (hdlgClose&)
           Local hwndact&, scan1&, scan2&
           scan1& = MapVirtualKey(%VK_MENU, 0)
           scan2& = MapVirtualKey(%VK_F4, 0)
           hwndact& = GetForegroundWindow
           SetForegroundWindow hdlgClose&
           KeyBd_Event %VK_MENU, scan1&, 0, 0: ApiSleep 20
           KeyBd_Event %VK_F4, scan2&, 0, 0: ApiSleep 20
           KeyBd_Event %VK_F4, scan2&, %KEYEVENTF_KEYUP, 0: ApiSleep 20
           KeyBd_Event %VK_MENU, scan1&, %KEYEVENTF_KEYUP, 0: ApiSleep 20
           SetForegroundWindow hwndact&
        End Sub
    
        CallBack Function hDlg_CB()
           Select Case CbMsg
              Case %WM_SETTEXT: Redrawn = %True
              Case %WM_DESTROY: Redrawn = %True: StopDn = 1
           End Select
       End Function
    
       Function ExecModeless (ByVal h&) As Long
          Dim hWindow As Long
    
          Dialog New %HWND_DESKTOP, "Progress Bar", _
             1, 1, 170, 50, %DS_CENTER, %WS_EX_TOPMOST To hPrDlg&
          Control Add "msctls_progress32", hPrDlg&, %ID_ProgressBar, "", 10, 10, 150, 15, %WS_BORDER Or %WS_VISIBLE Or %WS_CHILD, 0
          SendMessage GetDlgItem(hPrDlg&, %ID_ProgressBar), %PBM_SETRANGE, 0, MakLng(0,100)
          SendMessage GetDlgItem(hPrDlg&, %ID_ProgressBar), %PBM_SETPOS, 0, 0
          StopDn = 0
          Dialog Show Modal hPrDlg&, Call hDlg_CB
       End Function
    
       Sub StartModeless
          StopDn = -1
          Thread Create ExecModeless(h&) To hThread&
          Thread Close hThread& To lResult&
          While StopDn <> 0: Sleep 100: Wend
       End Sub
           
       Function PbMain
    
       Dim iPos As Long, w$
       StartModeless
       w$ = Time$
       Do
          If StopDn <> 0 Then Exit Do
          If Time$ <> w$ Then
             w$ = Time$
             iPos = iPos + 5: If iPos > 100 Then Exit Do
             Redrawn = %False
             SendMessage GetDlgItem(hPrDlg&, %ID_ProgressBar), %PBM_SETPOS, iPos, 0
             SetWindowText hPrDlg&, "Done " + Str$(iPos) + "%   (Press Alt-F4 to cancel)"
             While IsFalse(Redrawn): Sleep 20: Wend
          End If
       Loop
       If StopDn <> 1 Then StopModal hPrDlg& 
    End Function

    ------------------

    Leave a comment:


  • E B Knoppert
    Guest replied
    Very clear Lance..

    Thanks,



    ------------------

    Leave a comment:


  • Lance Edmonds
    replied
    Without discussing the non-standard (non-guaranteed) techniques suggested by others in this thread, a DIALOG DOEVENTS loop must execute for the entire duration of a MODELESS dialog.

    The reason for this is simple: any time that a message is placed in the message queue for the app, it must be dispatched to the dialog callback procedure. If this message pump (loop) is not running, then messages do not get forwarded and the dialog appears to "freeze".

    Consider this: If you only execute a limited number of DIALOG DOEVENTS statements in your code - what will happen when the dialog gets covered and uncovered by another app's window? The WM_PAINT (and associated messages) do not reach the modeless window procedure.

    This type of problem is not "predictable' by your own code (for example, your code cannot know when to repaint itself without help from Windows), so you have no choice by to execute a message loop if you want your modeless dialog to look and execute correctly.



    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Semen Matusovski
    replied
    Quick thought ...
    You calculate and change fields in main task.
    To be sure that DDT is redrawn, set "redrawn" flag in WM_PAINT event.
    Something like this:
    Code:
    Global Redrawn as Long
    CALLBACK FUNCTION for dialog in thread
      CASE %WM_PAINT
         Redrawn = %True
    
    In main task
    
    Redrawn = %False
    SendMessage to DDT
    While Redrawn = %False
       Sleep 50
    Wend
    ------------------

    Leave a comment:


  • E B Knoppert
    Guest replied
    Yes, i thought about that.

    The process takes only 3 seconds but is shown by a progressbar on a DDT dlg.
    There's a button to cancel, this button is not shown properly until i do another events.

    I like to have full control without using doevents if it's possible.

    I tried RedrawWindow API but maybe with the wrong settings..

    I think the thread will be executed after the calculations...
    Unpredictable results at least i guess.
    (Not my favourite)
    What i could do is do the calculations in the thread instead.
    Maybe speed is decreased??

    Thanks,



    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    EB --
    What about DIALOG SHOW MODAL inside thread (if to search, you can find how I solved the same problem for myself) ?
    In main program you continue calculation without worring about dialog doevents.

    ------------------

    Leave a comment:


  • E B Knoppert
    Guest started a topic DDT, refresh controls.

    DDT, refresh controls.

    I'm building a progress window using DDT.

    Before the dialog's controls are painted correctly, the procedure is doing it's job already.

    1 single Dialog Doevents is just not enough.

    1) Multiple can solve it but when to know when it's enough.
    2) I really wouldn't like to use this techn. because it gives the user the time to interfere.

    Thanks,

Working...
X
😀
🥰
🤢
😎
😡
👍
👎