Announcement

Collapse
No announcement yet.

DDT, refresh controls.

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

  • 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,


  • #2
    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.

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

    Comment


    • #3
      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,



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

      Comment


      • #4
        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
        ------------------

        Comment


        • #5
          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>
          Lance
          mailto:[email protected]

          Comment


          • #6
            Very clear Lance..

            Thanks,



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

            Comment


            • #7
              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

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

              Comment

              Working...
              X