home *** CD-ROM | disk | FTP | other *** search
/ BUG 4 / BUGCD1997_05.BIN / aplic / clip4win / clip4win.exe / C4W30E.HUF / SOURCE / DIALOGF2.PRG < prev    next >
Text File  |  1996-04-16  |  9KB  |  307 lines

  1. //    dialogf2.prg - dialog functions
  2. //
  3. //    Written by:    John M. Skelton,  Jun-94.
  4. //
  5. //    Copyright (C) 1994 Skelton Software, Kendal Cottage, Hillam, Leeds LS25 5HP, UK.
  6. //    All Rights Reserved.
  7. //
  8. //    Part of Clip-4-Win.
  9.  
  10. #define    WIN_WANT_CB
  11. #define    WIN_WANT_LB
  12. #define    WIN_WANT_ALL
  13. #include "windows.ch"
  14. //#include "topclass.ch"
  15. #include "vo.ch"
  16. #include "dialog.ch"
  17. #include "vbxbi.ch"
  18.  
  19. // saDlg is { aDlg, ... }
  20. // aDlg is:    from CreateDialog() or resource from _Create_Dialog() below
  21. #define    D_ID      1  // { cnId,        // in aDlg made by _Create_Dialog()
  22. #define    D_INST    2  //        hInst,
  23. #define    D_INITVBX 3  //              bInitVBX }
  24.  
  25. #define    D_MAX     4  // used to detect aDlg made by _Create_Dialog()
  26.  
  27.  
  28. // saParams is { aParams, ... }
  29. // aParams  is { aItem }
  30. // aItem    is:
  31. #define    P_ID      1  // { nId,        // but nil for a bInit block in bAction
  32. #define    P_WCLASS  2  //       cnWClass,
  33. #define    P_INIT      3  //                xInit,
  34. #define    P_ACTION  4  //                      bAction,
  35. #define    P_VALID      5  //                              bValid,
  36. #define    P_INIRET  6  //                                     xIniRet }
  37.  
  38. #define    P_VBX    P_WCLASS  //  cnWClass: shared with bVBX for INIT_PARAMS
  39. #define    P_MODAL    P_INIT    //           xInit: shared with lModal for INIT_PARAMS
  40.  
  41. STATIC GLOBAL    saDlg := {}
  42. STATIC GLOBAL    saParams := {} AS ARRAY    // OF ARRAY OF ARRAY, parallel to saDlg
  43.  
  44.  
  45. #command END DIALOG <hDlg>,<lModal>,<nwParam>                ;
  46.       => IF <lModal>                            ;
  47.        ;    EndDialog(<hDlg>, <nwParam>)                ;
  48.        ; ELSE                                ;
  49.        ;    DestroyWindow(<hDlg>)                    ;
  50.        ; END
  51.  
  52. #translate INIT_PARAMS(aParams) => atail(aParams)
  53.  
  54.  
  55. /*
  56.  *  This function returns an array (aDlg) to be similar to the Clip-4-Win API
  57.  *  function CreateDialog() - a little ugly but very convenient.
  58.  */
  59. function _Create_Dialog(cnId, hInst, bInitVBX)
  60. return {cnId, hInst, bInitVBX}  // A special aDlg made here!  Not for AppendDialog()
  61.  
  62.  
  63. function _Add_Dialog(aDlg, nId, cnWClass, xInit, bAction, bValid)
  64. local    i, hDlg,     a := {nId, cnWClass, xInit, bAction, bValid, nil}
  65. //                  also: {nil, bVBX,     lModal, bInit,  nil,    nil}
  66. if valtype(aDlg) == "N"
  67.     // an existing dialog
  68.     hDlg = aDlg
  69.     if nId != nil .and. xInit != nil
  70.         if valtype(cnWClass) == "N"
  71.             do case
  72.             case cnWClass == DLG_EDIT
  73.                 if valtype(xInit) == "B"    // a GET
  74.                     a[P_INIRET] = eval(xInit, hDlg)
  75.                 else
  76.                     SetWindowText(GetDlgItem(hDlg, nId), ;
  77.                                   xInit)
  78.                 endif
  79.             case cnWClass == DLG_COMBOBOX
  80.                 BoxInit(hDlg, a, .t.)
  81.             case cnWClass == DLG_LISTBOX
  82.                 if valtype(xInit) == "B"    // a browse
  83.                     a[P_INIRET] = eval(xInit, hDlg)
  84.                 else
  85.                     BoxInit(hDlg, a, .f.)
  86.                 endif
  87.             case cnWClass == DLG_STATIC
  88.                 SetWindowText(GetDlgItem(hDlg, nId), xInit)
  89.             case cnWClass == DLG_BUTTON
  90.                 SetWindowText(GetDlgItem(hDlg, nId), xInit)
  91.             endcase
  92.         endif
  93.     endif
  94. elseif (i := AScanExact(saDlg, aDlg)) == 0
  95.     if (i := AScanExact(saDlg, nil)) == 0
  96.         aadd(saDlg, aDlg)
  97.         i = len(saDlg)
  98.         aadd(saParams, {a})
  99.     else
  100.         saDlg[i] = aDlg
  101.         saParams[i] = {a}
  102.     endif
  103. else
  104.     aadd(saParams[i], a)
  105. endif
  106. return i
  107.  
  108.  
  109. function _Show_Dialog(aDlg, lModal, hWnd, bInit)
  110. local    nRet, nPos, cnId_aDlg, hInst, bVBX
  111.  
  112. if len(aDlg) < D_MAX
  113.     // resource dialog
  114.     cnId_aDlg = aDlg[D_ID]
  115.     hInst = aDlg[D_INST]
  116.     bVBX = aDlg[D_INITVBX]
  117. else
  118.     cnId_aDlg = aDlg
  119. //    hInst = nil        // it's nil anyway!
  120. //    bVBX = nil        // no auto-init resource
  121. endif
  122.  
  123. nPos = _Add_Dialog(aDlg, , bVBX, lModal, bInit)
  124.  
  125. if lModal
  126.     nRet = DialogBox(hInst, cnId_aDlg, hWnd,            ;
  127.              {|hDlg, nMsg, nwParam, nlParam|        ;
  128.               DlgProc(hDlg, nMsg, nwParam, nlParam, nPos)})
  129.     if nRet == -1
  130.         MessageBox(hWnd, "Dialog error e.g. resource not found", "Show Dialog")
  131.     endif
  132. else
  133.     nRet = CreateDialog(hInst, cnId_aDlg, hWnd,            ;
  134.                 {|hDlg, nMsg, nwParam, nlParam|        ;
  135.                  DlgProc(hDlg, nMsg, nwParam, nlParam, nPos)})
  136.     if nRet == 0
  137.         MessageBox(hWnd, "Dialog error e.g. resource not found", "Show Dialog")
  138.     endif
  139. endif
  140. return nRet
  141.  
  142.  
  143. static function DlgProc(hDlg, nMsg, nwParam, nlParam, nPos)
  144. local    nRet
  145.  
  146. do case
  147. case nMsg == WM_INITDIALOG
  148.     nRet = OnInitDialog(hDlg, nwParam, nlParam, saParams[nPos])
  149.  
  150. case nMsg == WM_COMMAND
  151.     nRet = OnCommand(hDlg, nwParam, nlParam, saParams[nPos])
  152.  
  153. case nMsg == WM_VBXFIREEVENT
  154.     nRet = OnVBXFireEvent(hDlg, nwParam, nlParam, saParams[nPos])
  155.  
  156. case nMsg == WM_NCDESTROY
  157.     // last message in the life of this dialog - clean up
  158.     saDlg[nPos] := saParams[nPos] := nil
  159.  
  160. otherwise
  161.     nRet = 0    // want default behaviour
  162. endcase
  163. return nRet
  164.  
  165.  
  166. static function BoxInit(hDlg, a, lCombo)
  167. local    hCtrl   := GetDlgItem(hDlg, a[P_ID])
  168. local    nReset  := iif(lCombo, CB_RESETCONTENT, LB_RESETCONTENT)
  169. local    nAdd    := iif(lCombo, CB_ADDSTRING,    LB_ADDSTRING)
  170. local    nSetSel := iif(lCombo, CB_SETCURSEL,    LB_SETCURSEL)
  171.  
  172. SendMessage(hCtrl, WM_SETREDRAW, 0, 0)
  173. SendMessage(hCtrl, nReset, 0, 0)
  174. aeval(a[P_INIT], {|c| SendMessage(hCtrl, nAdd, 0, c)})
  175. SendMessage(hCtrl, nSetSel, 0, 0)
  176. SendMessage(hCtrl, WM_SETREDRAW, 1, 0)
  177. return nil
  178.  
  179.  
  180. static function OnCommand(hDlg, nwParam, nlParam, aParams)
  181. local    nRet, i, bAction, hCtrl, nCode, lOk, bValid, nId, a
  182. /*
  183.  *  A message from a control.  We may have a code block to handle it.
  184.  */
  185. for i=1 to len(aParams)
  186.     if aParams[i, P_ID] == nwParam                ;
  187.     .and. (bAction := aParams[i, P_ACTION]) != nil
  188.         // bAction is {|hDlg, hCtrl, nCode, nId, xIniRet| ...}
  189.         hCtrl = C4W_LoWord(nlParam)
  190.         nCode = C4W_HiWord(nlParam)
  191.         nRet = eval(bAction, hDlg, hCtrl, nCode, nwParam, aParams[i, P_INIRET])
  192.         exit
  193.     endif
  194. next i
  195.  
  196. // default for Ok/Cancel, if not already handled
  197. if nRet == nil
  198.     do case
  199.     case nwParam == IDOK
  200.         // check DIALOG GETs are ok
  201.         lOk = IsDialogOK(hDlg)
  202.  
  203.         // check all VALID blocks are ok
  204.         for i=1 to len(aParams)
  205.             if (bValid := aParams[i, P_VALID]) != nil
  206.                 // bValid is {|hDlg, hCtrl, nId, xIniRet| ...}
  207.                 if !lOk
  208.                     exit
  209.                 endif
  210.                 a = aParams[i]
  211.                 nId = a[P_ID]
  212.                 hCtrl = GetDlgItem(hDlg, nId)
  213.                 lOk = eval(bValid, hDlg, hCtrl, nId, a[P_INIRET])
  214.             endif
  215.         next i
  216.         if lOk
  217.             END DIALOG hDlg, INIT_PARAMS(aParams)[P_MODAL], nwParam
  218.         endif
  219.         nRet = 1    // means msg handled
  220.     case nwParam == IDCANCEL
  221.         CANCEL DIALOG hDlg
  222.         END DIALOG hDlg, INIT_PARAMS(aParams)[P_MODAL], nwParam
  223.         nRet = 1    // means msg handled
  224.     endcase
  225. endif
  226.  
  227. // note: the default return value is 0 for this (and most) messages
  228. return iif(valtype(nRet) == "N" .and. nRet == 1, 1, 0)
  229.  
  230.  
  231. static function OnInitDialog(hDlg, nwParam, nlParam, aParams)
  232. local    nRet, i, n := len(aParams)
  233. local    bAction, a, cnWClass, aInitParams := INIT_PARAMS(aParams)
  234.  
  235. if aInitParams[P_VBX] != nil
  236.     eval(aInitParams[P_VBX], hDlg)
  237. endif
  238.  
  239. // do auto-init
  240. for i=1 to n
  241.     if (a := aParams[i])[P_ID] != nil .and. a[P_INIT] != nil
  242.         if valtype(cnWClass := a[P_WCLASS]) == "N"
  243.             do case
  244.             case cnWClass == DLG_EDIT
  245.                 if valtype(a[P_INIT]) == "B"    // a GET
  246.                     a[P_INIRET] = eval(a[P_INIT], hDlg)
  247.                 else
  248.                     SetWindowText(GetDlgItem(hDlg, a[P_ID]), ;
  249.                                   a[P_INIT])
  250.                 endif
  251.             case cnWClass == DLG_COMBOBOX
  252.                 BoxInit(hDlg, a, .t.)
  253.             case cnWClass == DLG_LISTBOX
  254.                 if valtype(a[P_INIT]) == "B"    // a browse
  255.                     a[P_INIRET] = eval(a[P_INIT], hDlg)
  256.                 else
  257.                     BoxInit(hDlg, a, .f.)
  258.                 endif
  259.             case cnWClass == DLG_STATIC
  260.                 SetWindowText(GetDlgItem(hDlg, a[P_ID]), ;
  261.                               a[P_INIT])
  262.             case cnWClass == DLG_BUTTON
  263.                 SetWindowText(GetDlgItem(hDlg, a[P_ID]), ;
  264.                               a[P_INIT])
  265.             endcase
  266.         endif
  267.     endif
  268. next i
  269.  
  270. // give user a chance
  271. if (bAction := aInitParams[P_ACTION]) != nil
  272.     // if bAction sets the input focus, it should return 0 
  273.     nRet = eval(bAction, hDlg, WM_INITDIALOG, nwParam, nlParam)
  274. endif
  275.  
  276. // note: the default return value below is 1 for this msg only
  277. //       (so by default the input focus is set automatically)
  278. return iif(valtype(nRet) == "N" .and. nRet == 0, 0, 1)
  279.  
  280.  
  281. static function OnVBXFireEvent(hDlg, nwParam, nlParam, aParams)
  282. local    aVBXEventStruct := Bin2A(C4W_Peek(nlParam, VBXEV_BYTELEN),    ;
  283.                              VBXEV_STRUCT_DEF)
  284. local    i, nId := aVBXEventStruct[VBXEV_ID], aInit, aEv, cEvent
  285.  
  286. for i=1 to len(aParams)
  287.     if aParams[i, P_ID] == nId
  288.         if (cEvent := aVBXEventStruct[VBXEV_EventName]) == nil
  289.             exit
  290.         endif
  291.         // found the control
  292.         aInit = aParams[i, P_INIT]
  293.         aEv = aInit[3]    // event info
  294.         for i=1 to len(aEv) step 2
  295.             if aEv[i] == cEvent
  296.                 //TBD: more params?
  297.                 eval(aEv[i + 1], hDlg, aVBXEventStruct)
  298.                 exit
  299.             endif
  300.         next i
  301.         exit
  302.     endif
  303. next i
  304. // note: the default return value is 0 for this (and most) messages
  305. return 1
  306.  
  307.