Author Topic: sequential vs events driven  (Read 17496 times)

JRS

  • Guest
Re: sequential vs events driven
« Reply #15 on: January 06, 2011, 11:44:13 PM »
If your not interested in my threaded adventures, here is a multi-window example running as a single process script in scriba.



Code: [Select]
DECLARE SUB DLL ALIAS "_idll" LIB "gtk-server"
DECLARE SUB DEFINE ALIAS "_idll_define" LIB "gtk-server"

DEFINE "gtk_init NONE NONE 2 NULL NULL"
DEFINE "gtk_window_new delete-event WIDGET 1 INT"
DEFINE "gtk_window_set_title NONE NONE 2 WIDGET STRING"
DEFINE "gtk_table_new NONE WIDGET 3 INT INT BOOL"
DEFINE "gtk_container_add NONE NONE 2 WIDGET WIDGET"
DEFINE "gtk_button_new_with_label clicked WIDGET 1 STRING"
DEFINE "gtk_table_attach_defaults NONE NONE 6 WIDGET WIDGET INT INT INT INT"
DEFINE "gtk_widget_show_all NONE NONE 1 WIDGET"
DEFINE "gtk_server_callback NONE STRING 1 STRING"
DEFINE "gtk_widget_destroy NONE NONE 1 WIDGET"
DEFINE "gtk_server_exit NONE NONE 0"

DLL("gtk_init NULL NULL")

FOR h = 1 to 10
  win[h] = DLL("gtk_window_new 0")
  DLL("gtk_window_set_title " & win[h] & " \"SB Gtk " & h & "\"")
  tbl[h] = DLL("gtk_table_new 10 10 1")
  DLL("gtk_container_add " & win[h] & " " & tbl[h])
  but[h] = DLL("gtk_button_new_with_label \"Quit\"")
  DLL("gtk_table_attach_defaults " & tbl[h] & " " & but[h] & " 5 9 5 9")
  DLL("gtk_widget_show_all " & win[h])
NEXT h

win_cnt = 10
REPEAT
  event = DLL("gtk_server_callback WAIT")
  FOR e = 1 TO 10
    IF event = win[e] OR event = but[e] THEN
      DLL("gtk_widget_destroy " & win[e])
      win_cnt -= 1
    END IF
  NEXT e
UNTIL win_cnt = 0

DLL("gtk_server_exit")

END
« Last Edit: January 07, 2011, 02:12:30 AM by JRS »

JRS

  • Guest
Re: sequential vs events driven
« Reply #16 on: January 07, 2011, 12:20:39 AM »
Gtk runs on Windows, Linux and the Mac. My Linux example would run untouched on Windows.



« Last Edit: January 07, 2011, 12:24:24 AM by JRS »

JRS

  • Guest
Re: sequential vs events driven
« Reply #17 on: January 10, 2011, 03:23:42 PM »
Aurel and Steve,

Any news on your efforts for Windows native GUI support for BXBasic or ABasic multi-window message handler?

There seemed to be some momentum in this area and I think it's a topic many Basic programmers have had a hard time getting a handle on.

John

« Last Edit: January 10, 2011, 04:12:33 PM by JRS »

JRS

  • Guest
Re: sequential vs events driven
« Reply #18 on: January 11, 2011, 05:49:58 AM »
I found an interesting link that gives a good explanation how the Windows message loop works and how it deals with multiple windows. This seems to be a science all of it's own.

http://www.winprog.org/tutorial/message_loop.html

Years ago James Fuller came up with a message cracker scheme that made dealing with Windows messages easier. Maybe James can chime in and unravel the mystery.
« Last Edit: January 11, 2011, 06:13:12 AM by JRS »

jcfuller

  • Guest
Re: sequential vs events driven
« Reply #19 on: January 11, 2011, 08:10:23 AM »

Years ago James Fuller came up with a message cracker scheme that made dealing with Windows messages easier. Maybe James can chime in and unravel the mystery.

For a compiler using Function Pointers. I doubt it would be applicable?

James

Steve A.

  • Guest
Re: sequential vs events driven
« Reply #20 on: January 11, 2011, 08:15:13 AM »
@ John:
    Thanks for the link. Helpful.

@ James:
    could you explain a little more about it, or, provide a link ?

Steve

jcfuller

  • Guest
Re: sequential vs events driven
« Reply #21 on: January 11, 2011, 10:25:32 AM »
@ James:
    could you explain a little more about it, or, provide a link ?

Steve


Steve,
 A little knowledge of PowerBASIC would help but with your background you should be able to see what I'm doing here.
If not just yell.
Note the original code was created by a code generator not by hand.

James
Code: [Select]
Ok this is how I did it for PowerBASIC.
All Dialog messages would go through the same event function here and use this udt:

#IF NOT %DEF(%cEventInfoType)
  %cEventInfoType = 1
  TYPE EventInfoType
    MaxDlgMsgs AS LONG
    DlgMsgs         AS DWORD PTR
    DlgProcs        AS DWORD PTR
    MaxCtlMsgs      AS LONG
    CtlMsgs         AS DWORD PTR
    CtlProcs        AS DWORD PTR
    MaxNotifyMsgs AS LONG
    NotifyCtlIds AS DWORD PTR
    NotifyProcs AS DWORD PTR
    ExitFlag AS LONG
  END TYPE
#ENDIF
'===========================================================================
'Dummy Declare for CALL DWORD Message Cracker
DECLARE _
  FUNCTION _
    DlgCallBackProc ( _
      BYVAL hDlg      AS DWORD,_
      BYVAL wMsg      AS DWORD,_
      BYVAL wParam    AS DWORD,_
      BYVAL lParam    AS LONG _
    ) AS LONG
'----------------------------------------------------------------------------
'~Dlg_Event_Proc            [Sub/Func Tag]
'----------------------------------------------------------------------------
FUNCTION _
  Dlg_Event_Proc ( _
    BYVAL hDlg AS DWORD,_
    BYVAL wMsg AS DWORD,_
    BYVAL wParam AS DWORD,_
    BYVAL lParam AS LONG _
  )  AS LONG

  DIM i AS LONG, _
      pEventInfo AS EventInfoType PTR, _
      dwTemp AS DWORD
 

  IF wMsg = %WM_INITDIALOG THEN
   
    #IF %DEF(%ADP_MACROS)
      m_SetDataInfo(hDlg,lParam)     
    #ELSE
      SetWindowLong hDlg,%DWL_USER,lParam
    #ENDIF 
   
    pEventInfo = lParam
    dwTemp = @pEventInfo.@DlgProcs[0]
  ELSE
    #IF %DEF(%ADP_MACROS)
      pEventInfo = m_GetDataInfo(hDlg)
    #ELSE
      pEventInfo = GetWindowLong(hDlg,%DWL_USER)
    #ENDIF 
    IF ISFALSE pEventInfo THEN
      EXIT FUNCTION
    END IF
    DO
      IF i > @pEventInfo.MaxDlgMsgs THEN
        EXIT DO
      END IF
      IF @pEventInfo.@DlgMsgs[i] = wMsg THEN
        dwTemp = @pEventInfo.@DlgProcs[i]
        EXIT DO
      END IF
      INCR i
    LOOP
  END IF
  IF dwTemp THEN
    CALL DWORD dwTemp _
      USING DlgCallBackProc(hDlg,_
                            wMsg,_
                            wParam,_
                            lParam) TO i
    FUNCTION = i
    SetWindowLong hDlg, %DWL_MSGRESULT, i
  END IF
  END FUNCTION
'***********************************************************************
'**********************************************************************


This is the Dialog code:


'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

'                  This Source Code was produced using PBWinADP

'        Target: Win32
'    Basic File: DLG_120.BAS
' Resource File: DLG_120.RC
'  Date Created: 12-31-2000
'  Time Created: 13:45:16

'Control & Menu ID EQUATES FOR DLG_120
'----------------------------------------------------------------------------
%DLG_120_CB_TSFTTP = 104
%DLG_120_CB_TSFTP = 105
%DLG_120_CB_TSATP = 106
%DLG_120_CB_SOST = 109
%DLG_120_CB_SOAT = 110
%DLG_120_CB_PFSUP = 111
%DLG_120_CB_BOAT = 107
%DLG_120_CB__PFSUS = 112
%DLG_120_CB_SOFT = 108
%DLG_120_IDC_BUTTON10 = 102
%DLG_120_IDC_STATICFRAME1 = 103
%DLG_120_IDC_STATICTEXT1 = 113
%DLG_120_IDC_RADIOBUTTON1 = 114
%DLG_120_IDC_RADIOBUTTON2 = 115
%DLG_120_IDC_RADIOBUTTON3 = 116
%DLG_120_IDC_STATICFRAME2 = 117
%DLG_120_CB_TA = 121
%DLG_120_RB_IMPERIAL = 120
%DLG_120_RB_METRIC = 119

'----------------------------------------------------------------------------
'The following UDT is used for encapsulation of message cracker arrays.
'If you need any private data just add to the UDT.
'----------------------------------------------------------------------------
TYPE DLG_120_InfoType
  MaxDlgMsgs           AS LONG
  DlgMsgs              AS DWORD PTR
  DlgProcs             AS DWORD PTR
  MaxCtlMsgs           AS LONG
  CtlMsgs              AS DWORD PTR
  CtlProcs             AS DWORD PTR
  MaxNotifyMsgs        AS LONG
  NotifyCtlIds         AS DWORD PTR
  NotifyProcs          AS DWORD PTR
  ExitFlag             AS LONG
  DlgId    AS LONG
  IsModal    AS LONG
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'>> DO NOT ALTER ANYTHING ABOVE. ADD ALL NEW ENTRIES BELOW
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
END TYPE
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'                    FUNCTION PROTOTYPES
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'----------------------------------------------------------------------------
'Call the following function to create your dialog.
'The function expects a global instance handle of ghInst.
'This var is created if you use RC2BAS to create your main dialog
'The function will return %FALSE if there was an error
'hWnd is the handle of the calling Window/Dialog.
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'~Create_DLG_120          [Sub/Func Tag]
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
FUNCTION _
  Create_DLG_120 ( _
    hWnd AS DWORD _
  ) AS LONG

  DIM lpMem AS DWORD,_
      lpDataInfo AS DLG_120_InfoType PTR, _
      MsgIndex AS LONG, _
      MemOffset AS DWORD, _
      RetVal AS LONG
  DIM hDlg AS DWORD
  lpMem = HeapAlloc(ghHeap,0 OR %HEAP_ZERO_MEMORY,LEN(DLG_120_InfoType))
  IF ISFALSE lpMem THEN
    MsgBox "Not Able to Allocate Mem"
    FUNCTION = 0
    EXIT FUNCTION
  END IF
  lpDataInfo = lpMem
  @lpDataInfo.DlgId = 120
  @lpDataInfo.IsModal = 0

'---------------------------------------------------------------------------
'>> Message Crackers
  #INCLUDE "DLG_120.MSG"

  hDlg = CreateDialogParam(ghInst,BYVAL 120,hWnd,CODEPTR(Dlg_Event_Proc),lpMem)
  IF ISFALSE hDlg THEN
    HeapFree ghHeap,0,@lpDataInfo.DlgMsgs
    HeapFree ghHeap,0,lpMem
    FUNCTION = 0
    EXIT FUNCTION
  END IF
  ghMainMenu = hDlg
  ShowWindow hDlg,%SW_SHOW
  FUNCTION = hDlg
END FUNCTION              'Create_DLG_120
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'~Dlg_120_ShowPickListForm
'------------------------------------------------------------------------------
FUNCTION _
  Dlg_120_ShowPickListForm ( _
    BYVAL hDlg      AS DWORD,_
    BYVAL wMsg      AS DWORD,_
    BYVAL wParam    AS DWORD,_
    BYVAL lParam    AS LONG _
  ) AS LONG

  LOCAL IdVal&, _
        IdCodePtr AS DWORD, _
        RetVal&, _
        szTitle AS ASCIIZ * 80

  IdVal& = LOWRD(wParam)
  IF IsDlgButtonChecked(hDlg,%DLG_120_IDC_RADIOBUTTON1) THEN
    IF IdVal& = %DLG_120_CB_TSFTTP THEN
      IdCodePtr = %Dlg_220'CODEPTR(Create_Dlg_220)
      szTitle = "SDJ Electra [-CAD4OCS-] Trolley System Fixed Termination Trolley Pole"
    ELSEIF IdVal& = %DLG_120_CB_TSFTP THEN
      IdCodePtr = %Dlg_300'CODEPTR(Create_Dlg_300)
      szTitle = "SDJ Electra [-CAD4OCS-] Trolley System Fixed Termination Pantograph" 
    ELSEIF IdVal& = %DLG_120_CB_TSATP THEN
      IdCodePtr = %Dlg_400'CODEPTR(Create_Dlg_400)
      szTitle = "SDJ Electra [-CAD4OCS-] Trolley System Auto Tensioned Pantograph" 
    ELSEIF IdVal& = %DLG_120_CB_SOST THEN
      IdCodePtr = %Dlg_700'CODEPTR(Create_Dlg_700)
      szTitle = "SDJ Electra [-CAD4OCS-] Simple OCS Semi Tensioned"
    ELSEIF IdVal& = %DLG_120_CB_SOAT THEN
      IdCodePtr = %Dlg_800'CODEPTR(Create_Dlg_800)
      szTitle = "SDJ Electra [-CAD4OCS-] Simple OCS Auto Tensioned"
    ELSEIF IdVal& = %DLG_120_CB_PFSUP THEN
      IdCodePtr = %Dlg_900'CODEPTR(Create_Dlg_900)
      szTitle = "SDJ Electra [-CAD4OCS-] Parallel Feeders Supported"
    ELSEIF IdVal& = %DLG_120_CB_BOAT THEN
      IdCodePtr = %Dlg_500'CODEPTR(Create_Dlg_500)
      szTitle = "SDJ Electra [-CAD4OCS-]  Bridle OCS Auto Tensioned"
    ELSEIF IdVal& = %DLG_120_CB__PFSUS THEN
      IdCodePtr = %Dlg_1000'CODEPTR(Create_Dlg_1000)
      szTitle = "SDJ Electra [-CAD4OCS-] Parallel Feeders Suspended"
    ELSEIF IdVal& = %DLG_120_CB_SOFT THEN
      IdCodePtr = %Dlg_600'CODEPTR(Create_Dlg_600)
      szTitle = "SDJ Electra [-CAD4OCS-] Simple OCS Fixed Termination"
    ELSEIF IdVal& =   %DLG_120_CB_TA THEN
      'MessageBox hDlg,"Shell To Track Alignment Data Input","Track Alignment",%MB_OK
      IdCodePtr = %Dlg_1300'CODEPTR(Create_Dlg_1300)
      szTitle = "SDJ Electra [-CAD4OCS-] Track Alignment"
    END IF
  ELSEIF IsDlgButtonChecked(hDlg,%DLG_120_IDC_RADIOBUTTON2) THEN
    IF IdVal& = %DLG_120_CB_TSFTTP THEN
      IdCodePtr = %Dlg_1600
      szTitle = "SDJ Electra [-CAD4OCS-] Trolley System Fixed Termination Trolley Pole Calculations"
    END IF 
'     IF IdVal& =   %DLG_120_CB_TA THEN
'       IdCodePtr = CODEPTR(Create_Dlg_1200)
       'gTrackAlignFlag = 1
'       MessageBox hDlg,"Do Track Alignment Calculations","Track Alignment",%MB_OK
'       EXIT FUNCTION
'     END IF 
'    IF IdVal& = %DLG_120_CB_TSFTTP THEN
      'Create_Dlg_1100 hDlg
 '   ELSE
 '   MessageBox hDlg,"Calculations are not Implemented at present","Comming soon....",%MB_OK
 '   END IF
  ELSEIF IsDlgButtonChecked(hDlg,%DLG_120_IDC_RADIOBUTTON3) THEN   
    MessageBox hDlg,"Reports are not Implemented at present","No Reports",%MB_OK
  END IF
   
   

  IF IdCodePtr THEN
    ShowWindow hDlg,%SW_HIDE
    ghCurrentPickList& = ghPickList&(IdCodePtr)
    ShowWindow ghCurrentPickList&,%SW_SHOW
    SetWindowText ghHoldWin, szTitle
    ShowWindow ghDlg1400,%SW_SHOW
'    ShowWindow ghDlg1400,%SW_HIDE
'    CALL DWORD IdCodePtr USING Create_Dlg_220(GetParent(hDlg)) 
'    CALL DWORD IdCodePtr USING Create_Dlg_220(ghDlg1400) 
  END IF 
   
   
   
END FUNCTION 
'============================================================================
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'Message Cracker Functions For DLG_120
'============================================================================
'>> Dialog Functions
'============================================================================
'============================================================================
'~DLG_120_Onwmactivate            [Sub/Func Tag]
'============================================================================
FUNCTION _
  DLG_120_Onwmactivate ( _
    BYVAL hDlg        AS DWORD,_
    BYVAL wMsg        AS DWORD,_
    BYVAL wParam      AS DWORD,_
    BYVAL lParam      AS DWORD _
  ) AS DWORD

  DIM lpDataInfo       AS DLG_120_InfoType PTR

  lpDataInfo = m_GetDataInfo(hDlg)


 
END FUNCTION
'============================================================================
'~DLG_120_OnWmInitDialog           [Sub/Func Tag]
'============================================================================
FUNCTION _
  DLG_120_OnWmInitDialog ( _
    BYVAL hDlg        AS DWORD,_
    BYVAL wMsg        AS DWORD,_
    BYVAL wParam      AS DWORD,_
    BYVAL lParam      AS LONG _
  ) AS LONG

'  DIM lpDataInfo       AS DLG_120_InfoType PTR

'  lpDataInfo = GetWindowLong(hDlg,%DWL_USER)

  Initialize_Controls hDlg
'---------------------------------------------------------------------------
  CenterWindow hDlg
  CheckDlgButton hDlg,%DLG_120_IDC_RADIOBUTTON1,%BST_CHECKED
  CheckDlgButton hDlg,%DLG_120_RB_METRIC, %BST_CHECKED
'  PostMessage ghHoldWin,%WM_MAKE_1400,0,0
 FUNCTION = 1
END FUNCTION
'============================================================================
'~DLG_120_OnWmDestroy          [Sub/Func Tag]
'============================================================================
FUNCTION _
  DLG_120_OnWmDestroy ( _
    BYVAL hDlg AS DWORD,_
    BYVAL wMsg AS DWORD,_
    BYVAL wParam AS DWORD,_
    BYVAL lParam AS LONG _
  ) AS LONG

  DIM lpDataInfo      AS DLG_120_InfoType PTR

  #IF %TRACEIT = 2
    TRACE ON
    TRACE PRINT "WM _DESTROY IN " + FUNCNAME$
    TRACE OFF
  #ENDIF

  lpDataInfo = m_GetDataInfo(hDlg)'GetWindowLong(hDlg,%DWL_USER)
 
  #IF %DEF(%DLG_120_USE_OD_BUTTONS)
    EnumChildWindows hDlg,CODEPTR(ODButFreeMem2),0
  #ENDIF

  EnumChildWindows hDlg,CODEPTR(Control_FreeMem),0
 
  IF lpDataInfo THEN
   
      HeapFree ghHeap,0,@lpDataInfo.DlgMsgs
      HeapFree ghHeap,0,lpDataInfo
 
     
    m_setDataInfo(hDlg,0)
  END IF 
'  PostMessage GetParent(hDlg),%WM_CLOSE,0,0 
 FUNCTION = 0
END FUNCTION
'============================================================================
'~DLG_120_OnWmClose            [Sub/Func Tag]
'============================================================================
FUNCTION _
  DLG_120_OnWmClose ( _
    BYVAL hDlg        AS DWORD,_
    BYVAL wMsg        AS DWORD,_
    BYVAL wParam      AS DWORD,_
    BYVAL lParam      AS LONG _
  ) AS LONG

  DestroyWindow hDlg
  FUNCTION = 0
END FUNCTION
'============================================================================
'============================================================================
'~DLG_120_OnWmDrawItem            [Sub/Func Tag]
'============================================================================
FUNCTION _
  DLG_120_OnWmDrawItem ( _
    BYVAL hDlg AS DWORD,_
    BYVAL wMsg      AS DWORD,_
    BYVAL wParam    AS DWORD,_
    BYVAL lParam    AS DWORD _
  ) AS DWORD

#IF %DEF(%DLG_120_USE_OD_BUTTONS)

 
  LOCAL lpODButInfo AS ODBut_InfoType PTR ,_
        di AS DRAWITEMSTRUCT PTR,_
        lpCtlInfo AS ControlInfoType PTR, _
        bm AS BITMAP,_
      hBitmap AS DWORD,_
      rFocus AS RECT,_
      DcRect            AS RECT,_
      NoFocusFlag       AS INTEGER

  di = lParam

  lpCtlInfo = GetProp(@di.hWndItem,"CtlInfo")
  IF ISFALSE lpCtlInfo THEN
    EXIT FUNCTION
  END IF
   
  lpODButInfo = @lpCtlInfo.dwx

  IF ISFALSE lpODButInfo THEN
    EXIT FUNCTION
  END IF
  IF (@di.ItemState AND %ODS_SELECTED) THEN
    hBitMap = @lpODButInfo.hBitmapDn
    rFocus = @lpODButInfo.rFocusDn
  ELSE
    hBitmap = @lpODButInfo.hBitmapUp
    rFocus = @lpODButInfo.rFocusUp
  END IF
  GetObject hBitmap,LEN(BITMAP),bm
  DcRect.nRight = bm.bmWidth
  DcRect.nBottom = bm.bmHeight

  IF (@di.ItemAction AND %ODA_DRAWENTIRE) OR _
    (@di.ItemAction AND %ODA_SELECT) THEN
    PaintBitmap @di.hDc,DcRect,hBitMap,DcRect,@lpODButInfo.hPal
  END IF

  'Need some code for focus
  IF ISFALSE @lpODButInfo.NoFocusFlag  THEN
    IF (@di.ItemState AND %ODS_FOCUS) THEN
      FrameRect @di.hDc,rFocus,GetStockObject(%DKGRAY_BRUSH)
    END IF
  END IF
  FUNCTION = 1
#ENDIF
END FUNCTION
'============================================================================
'>> Control Functions
'============================================================================
'~DLG_120_IDC_BUTTON10_OnClick          [Sub/Func Tag]
'============================================================================
FUNCTION _
  DLG_120_IDC_BUTTON10_OnClick ( _
    BYVAL hDlg      AS DWORD,_
    BYVAL wMsg      AS DWORD,_
    BYVAL wParam    AS DWORD,_
    BYVAL lParam    AS LONG _
  ) AS LONG

   'SendMessage ghPickList&(%Dlg_1400),%WM_CLOSE,0,0
   PostMessage GetParent(hDlg),%WM_MAKE_1400,hDlg,0 
END FUNCTION
'============================================================================
'***********************************************************************
'***********************************************************************




And this is the setup for the callabcks:
This is the   #INCLUDE "DLG_120.MSG" file from the code above


'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
'DLG_120
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
@lpDataInfo.MaxDlgMsgs = 10
@lpDataInfo.MaxCtlMsgs = 11
@lpDataInfo.MaxNotifyMsgs =  0
'---------------------------------------------------------------------------
MemOffset = HeapAlloc(ghHeap,%HEAP_ZERO_MEMORY,(@lpDataInfo.MaxDlgMsgs + _
                               @lpDataInfo.MaxCtlMsgs + _
                               @lpDataInfo.MaxNotifyMsgs)*8)
IF ISFALSE MemOffset THEN
  MsgBox "Message Array memory allocation error"
  FUNCTION = 0
  EXIT FUNCTION
END IF
'---------------------------------------------------------------------------
IF @lpDataInfo.MaxDlgMsgs THEN
   @lpDataInfo.DlgMsgs = MemOffset
   MemOffset = MemOffset + (@lpDataInfo.MaxDlgMsgs * 4)
   @lpDataInfo.DlgProcs = MemOffset
   MemOffset = MemOffset + (@lpDataInfo.MaxDlgMsgs * 4)
END IF
IF @lpDataInfo.MaxCtlMsgs THEN
   @lpDataInfo.CtlMsgs = MemOffset
   MemOffset = MemOffset + (@lpDataInfo.MaxCtlMsgs * 4)
   @lpDataInfo.CtlProcs = MemOffset
   MemOffset = MemOffset + (@lpDataInfo.MaxCtlMsgs * 4)
END IF
IF @lpDataInfo.MaxNotifyMsgs THEN
   @lpDataInfo.NotifyCtlIds =  MemOffset
   MemOffset = MemOffset + (@lpDataInfo.MaxNotifyMsgs * 4)
   @lpDataInfo.NotifyProcs = MemOffset
END IF
'===========================================================================
'>> BEGIN DLG_MSGS
'===========================================================================
  MsgIndex = 0
'---------------------------------------------------------------------------
'~%WM_INITDIALOG   (%WM_INITDIALOG IS ALWAYS FIRST)
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_INITDIALOG
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(DLG_120_OnWmInitDialog)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_COMMAND
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_COMMAND
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(Ctl_Event_Proc)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_CTLCOLORSTATIC
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_CTLCOLORSTATIC
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(WM_CTLCOLOR_Proc)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_CTLCOLORBTN
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_CTLCOLORBTN
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(WM_CTLCOLOR_Proc)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_CTLCOLOREDIT
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_CTLCOLOREDIT
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(WM_CTLCOLOR_Proc)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_CTLCOLORLISTBOX
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_CTLCOLORLISTBOX
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(WM_CTLCOLOR_Proc)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_CLOSE
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_CLOSE
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(DLG_120_OnWmClose)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_DESTROY
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_DESTROY
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(DLG_120_OnWmDestroy)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_DRAWITEM
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_DRAWITEM
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(DLG_120_OnWmDrawItem)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~%WM_ACTIVATE
'---------------------------------------------------------------------------
  @lpDataInfo.@DlgMsgs[MsgIndex] = %WM_ACTIVATE
  @lpDataInfo.@DlgProcs[MsgIndex] = CODEPTR(DLG_120_Onwmactivate)
  INCR MsgIndex
'---------------------------------------------------------------------------
'>> END DLG_MSGS
'===========================================================================
'>> BEGIN CTL_MSGS
'===========================================================================
  MsgIndex = 0
'---------------------------------------------------------------------------
'~DLG_120_CB_TSFTTP_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_TSFTTP,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_TSFTP_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_TSFTP,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_TSATP_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_TSATP,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_SOST_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_SOST,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_SOAT_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_SOAT,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_PFSUP_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_PFSUP,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_BOAT_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_BOAT,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB__PFSUS_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB__PFSUS,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_CB_SOFT_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_SOFT,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~DLG_120_IDC_BUTTON10_OnClick >> %BN_CLICKED <<
'---------------------------------------------------------------------------
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_IDC_BUTTON10,%BN_CLICKED)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(DLG_120_IDC_BUTTON10_OnClick)
  INCR MsgIndex
'---------------------------------------------------------------------------
'~Dlg_120_ShowPickListForm    << MENU >>
  @lpDataInfo.@CtlMsgs[MsgIndex] = MAKDWD(%DLG_120_CB_TA,0)
  @lpDataInfo.@CtlProcs[MsgIndex] = CODEPTR(Dlg_120_ShowPickListForm)
  INCR MsgIndex
''---------------------------------------------------------------------------
'>> END CTL_MSGS
'===========================================================================
'>> BEGIN NOTIFY_MSGS
'===========================================================================
  MsgIndex = 0
'---------------------------------------------------------------------------
'>> END NOTIFY_MSGS
'===========================================================================
'~EOM         End of Messages
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=









JRS

  • Guest
Re: sequential vs events driven
« Reply #22 on: January 11, 2011, 10:09:47 PM »
No one said that managing the Windows message loop was going to be easy. It's amazing the number of messages, the rules, the weirdness and then have to catch the few messages you really care about. I'm so glad I made the Linux and Gtk move. I get more done with less code. The other benefit I see using Gtk is if you see something in an application that attracts you, look at the code (doesn't matter what language it is) and see how the Gtk functions are used to help build your own application.
« Last Edit: January 11, 2011, 10:21:53 PM by JRS »

JRS

  • Guest
Re: sequential vs events driven
« Reply #23 on: January 12, 2011, 11:31:22 AM »
I could use some help defining this Windows structure to pass as an argument in ScriptBasic for Windows. I'm going to use the DYC (DynaCall) extension module to script a simple window (winAPI  style) for tutorial purposes. SB is a nice way to prototype a concept.

Code: [Select]
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;

    // Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wc)
    }

  • cbSize The size of the structure.
  • style Class Styles (CS_*), not to be confused with Window Styles (WS_*) This can usually be set to 0.
  • lpfnWndProc Pointer to the window procedure for this window class.
  • cbClsExtra Amount of extra data allocated for this class in memory. Usually 0.
  • cbWndExtra Amount of extra data allocated in memory per window of this type. Usually 0.
  • hInstance Handle to application instance (that we got in the first parameter of WinMain()).
  • hIcon Large (usually 32x32) icon shown when the user presses Alt+Tab.
  • hCursor Cursor that will be displayed over our window.
  • hbrBackground Background Brush to set the color of our window.
  • lpszMenuName Name of a menu resource to use for the windows with this class.
  • lpszClassName Name to identify the class with.
  • hIconSm Small (usually 16x16) icon to show in the taskbar and in the top left corner of the window.


lpfnWndProc will be the challenge for SB.

Quote
The window procedure is called for each message, the HWND parameter is the handle of your window, the one that the message applies to. This is important since you might have two or more windows of the same class and they will use the same window procedure (WndProc()). The difference is that the parameter hwnd will be different depending on which window it is. For example when we get the WM_CLOSE message we destroy the window. Since we use the window handle that we received as the first paramter, any other windows will not be affected, only the one that the message was intended for.

I can see right off the bat that creating this Windows class structure and returning a pointer to it is best done at the BCX level. I'm setting up my Wine SB Windows development environment and will post the current SBAPI.dll source to this thread when done. At this point it will have the SB VARPTR and a new GenWinClass helper functions along with the statically linked libscriba.obj.
« Last Edit: January 12, 2011, 02:49:22 PM by JRS »

JRS

  • Guest
Re: sequential vs events driven
« Reply #24 on: January 12, 2011, 05:33:31 PM »
The Windows DYC ScriptBasic extension module works under Linux/Wine. Glad I don't have to do this under Windows.



Code: [Select]
DECLARE SUB DLL ALIAS "dyc" LIB "dyc"

PRINT DLL("ms,i,USER32.DLL,MessageBox,PZZL", 0, "message text", "title", 3)

C:\scriptbasic\test>
6
C:\scriptbasic\test>

Quote
Titlebar Exit = 2
Yes = 6
No = 7
Cancel = 2

I was curious why the msgbox wasn't using the XP theme that I assigned to Wine. I tried the same thing under Windows and it had the same Win2000 style buttons.

« Last Edit: January 12, 2011, 07:13:25 PM by JRS »

JRS

  • Guest
Re: sequential vs events driven
« Reply #25 on: January 12, 2011, 08:33:22 PM »
Can a window callback procedure point to an exported DLL function?

I'm trying to use the same concept as Peter did with gtk_server_callback WAIT.

AutoIt has an interesting approach to dealing with callbacks. DllCallBack  DllStructCreate

Here is an example of it's use.

Code: [Select]
#include "DllCallBack.au3"



Global $sOut

$hStub_EnumChildProc = _DllCallBack ("_EnumChildProc", "hwnd;ptr")

Func _EnumChildProc($hWnd, $lParam)

$hWnd = HWnd($hWnd)

$sOut &= "hWnd: " & $hWnd & @CRLF

Return 1

EndFunc   ;==>_EnumChildProc

$hWnd_Parent = WinGetHandle("[ACTIVE]") ; SciTE

DllCall("user32.dll", "int", "EnumChildWindows", "hwnd", $hWnd_Parent, "ptr", $hStub_EnumChildProc, "ptr", 0)

ConsoleWrite($sOut & @CRLF)

_DllCallBack_Free ($hStub_EnumChildProc)


« Last Edit: January 13, 2011, 12:49:46 AM by JRS »