home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / DIALOG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  13.7 KB  |  546 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   source\owl\dialog.cpp
  4. //   Defines type TDialog.  This defines the basic behavior of all dialogs.
  5. //----------------------------------------------------------------------------
  6. #pragma hdrignore SECTION
  7. #include <owl\owlpch.h>
  8. #include <owl\dialog.h>
  9. #include <owl\applicat.h>
  10. #include <string.h>
  11. #include <bwcc.h>
  12.  
  13. DIAG_DECLARE_GROUP(OwlMsg);  // diagnostic group for message tracing
  14. DIAG_DECLARE_GROUP(OwlWin);  // diagnostic group for windows
  15.  
  16. #if !defined(SECTION) || SECTION == 1
  17.  
  18. #if !defined(RT_DLGINIT)
  19.   #define RT_DLGINIT       MAKEINTRESOURCE(240)
  20. #endif
  21.  
  22. extern UINT _OWLDATA GetWindowPtrMsgId; // in owl.cpp
  23.  
  24. //
  25. // Our exported dialog proc & its proc instance
  26. //
  27. BOOL FAR PASCAL _export StdDlgProc(HWND, UINT, WPARAM, LPARAM);
  28. TProcInstance StdDlgProcInstance((FARPROC)StdDlgProc);
  29.  
  30. TDialog* _OWLDATA DlgCreationWindow = 0;  // public so derived classes can create
  31.  
  32. DEFINE_RESPONSE_TABLE1(TDialog, TWindow)
  33.   EV_WM_CLOSE,
  34.   EV_WM_PAINT,
  35.   EV_WM_CTLCOLOR,
  36.   EV_COMMAND(IDOK, CmOk),
  37.   EV_COMMAND(IDCANCEL, CmCancel),
  38. END_RESPONSE_TABLE;
  39.  
  40. //
  41. // constructor for a TDialog object
  42. //
  43. // takes an TResId for its template name or numeric Id
  44. //
  45. TDialog::TDialog(TWindow* parent, TResId resId, TModule* module)
  46. {
  47.   //
  48.   // Initialize virtual base, in case the derived-most used default ctor
  49.   //
  50.   TWindow::Init(parent, 0, module);
  51.  
  52.   DisableAutoCreate();
  53.   if (HIWORD(Title))
  54.     delete Title;
  55.   Title = (LPSTR)MAKEINTRESOURCE(0xFFFF); // Title setting--"don't-change"
  56.  
  57.   SetFlag(wfFromResource);
  58.   Attr.Param = 0;
  59.   IsModal = FALSE;
  60.   Attr.Name = resId.IsString() ? strnewdup(resId) : (char far*)resId;
  61. }
  62.  
  63. //
  64. // destructor for a TDialog
  65. //
  66. // ~TWindow frees the instance thunk
  67. //
  68. TDialog::~TDialog()
  69. {
  70.   if (HIWORD(Attr.Name))
  71.     delete Attr.Name;
  72. }
  73.  
  74. BOOL
  75. TDialog::PreProcessMsg(MSG& msg)
  76. {
  77.   if (TWindow::PreProcessMsg(msg))
  78.     return TRUE;  // process accelerators
  79.  
  80.   else
  81.     return ::IsDialogMessage(HWindow, &msg);
  82. }
  83.  
  84. char far*
  85. TDialog::GetClassName()
  86. {
  87.   if (GetApplication()->BWCCEnabled())
  88.     return BORDLGCLASS;
  89.   else
  90.     return (char far*)WC_DIALOG;
  91. }
  92.  
  93. void
  94. TDialog::GetWindowClass(WNDCLASS& wndClass)
  95. {
  96.   TResId dlgClass;
  97.  
  98.   if (GetApplication()->BWCCEnabled()) {
  99.     BOOL FAR PASCAL(*bwccRegister)(HINSTANCE);
  100.     (FARPROC)bwccRegister = GetApplication()->GetBWCCModule()->GetProcAddress("BWCCRegister");
  101.     if (bwccRegister)
  102.       (*bwccRegister)(*GetModule());
  103.  
  104.     dlgClass = BORDLGCLASS;
  105.  
  106.   } else
  107.     dlgClass = WC_DIALOG;
  108.  
  109.   if (!::GetClassInfo(0, dlgClass, &wndClass))
  110.     GetModule()->GetClassInfo(dlgClass, &wndClass);
  111.  
  112.   wndClass.lpszClassName = GetClassName();
  113. }
  114.  
  115. void
  116. TDialog::EvSetFont(HFONT)
  117. {
  118. }
  119.  
  120. void
  121. TDialog::EvPaint()
  122. {
  123.   DefaultProcessing();  // don't call TWindow::EvPaint()
  124. }
  125.  
  126. //
  127. // If this app is using Ctl3d, forward the WM_CTLCOLOR message to the
  128. // ctl3d.dll since it needs to handle that & we don't let it autosubclass
  129. //
  130. HBRUSH
  131. TDialog::EvCtlColor(HDC hDC, HWND hWndChild, UINT ctlType)
  132. {
  133.   if (GetApplication()->Ctl3dEnabled()) {
  134.     static HBRUSH FAR PASCAL(*ctl3dCtlColorEx)(UINT, WPARAM, LPARAM) = 0;
  135.     if (!ctl3dCtlColorEx)
  136.       (FARPROC)ctl3dCtlColorEx = GetApplication()->GetCtl3dModule()->
  137.                                    GetProcAddress("Ctl3dCtlColorEx");
  138.  
  139.     HBRUSH hBr = 0;
  140.     if (ctl3dCtlColorEx)
  141.       #if defined(__WIN32__)
  142.         hBr = ctl3dCtlColorEx(WM_CTLCOLORMSGBOX+ctlType, WPARAM(hDC), LPARAM(hWndChild));
  143.       #else
  144.         hBr = ctl3dCtlColorEx(WM_CTLCOLOR, WPARAM(hDC), MAKELPARAM(hWndChild, ctlType));
  145.       #endif
  146.  
  147.     if (hBr)
  148.       return hBr;
  149.   }
  150.   return TWindow::EvCtlColor(hDC, hWndChild, ctlType);
  151. }
  152.  
  153. //
  154. // The default dialog function. Handles the two mesages, WM_INITDIALOG and
  155. // WM_SETFONT that may be sent before we get a chance to thunk
  156. // DIALOG's window proc.
  157. //
  158. BOOL
  159. TDialog::DialogFunction(UINT msg, WPARAM wParam, LPARAM lParam)
  160. {
  161.   TRACEX(OwlMsg, 2, MsgName(msg) << "(DlgFcn)=> " << *this);
  162.  
  163.   switch (msg) {
  164.     case WM_INITDIALOG:
  165.       return EvInitDialog((HWND)wParam);
  166.  
  167.     case WM_SETFONT:
  168.       EvSetFont((HFONT)wParam);
  169.       return TRUE;
  170.  
  171.     case WM_SETTEXT:
  172.     case WM_NCPAINT:
  173.     case WM_NCACTIVATE:
  174.       if (GetApplication()->Ctl3dEnabled()) {
  175.         static BOOL FAR PASCAL(*ctl3dDlgFramePaint)(HWND, UINT, WPARAM, LPARAM) = 0;
  176.         if (!ctl3dDlgFramePaint)
  177.           (FARPROC)ctl3dDlgFramePaint = GetApplication()->GetCtl3dModule()->
  178.                                           GetProcAddress("Ctl3dDlgFramePaint");
  179.         if (ctl3dDlgFramePaint) {
  180.           SetWindowLong(DWL_MSGRESULT, (*ctl3dDlgFramePaint)(HWindow, msg, wParam, lParam));
  181.           return TRUE;
  182.         }
  183.       }
  184.       break;
  185.   }
  186.   return FALSE;  // not handled
  187. }
  188.  
  189. //
  190. // Handles messages that comes from WC_DIALOG's wndProc
  191. // DlgCreationWindow is not 0, is destined for DlgCreationWindow.
  192. // Setup DlgCreationWindow's HWindow, subclass the WC_DIALOG class's window
  193. // function. Calls the virtual DialogFunction() to handle specific messages
  194. //
  195. BOOL FAR PASCAL _export
  196. StdDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  197. {
  198.   //
  199.   // Thunk on first message to a non-thunked window & thats not one sent to
  200.   // parent dialogs.
  201.   //
  202.   if (msg == GetWindowPtrMsgId) // if it gets here, we wont know how to get it
  203.     return FALSE;
  204.  
  205.   TWindow*  w = GetWindowPtr(hDlg);
  206.   TDialog*  dialog = TYPESAFE_DOWNCAST(w, TDialog);
  207.  
  208.   if (DlgCreationWindow && !dialog && msg != WM_CANCELMODE && msg != WM_ENABLE) {
  209.     DlgCreationWindow->HWindow = hDlg;
  210.  
  211.     DlgCreationWindow->SubclassWindowFunction();
  212.     dialog = DlgCreationWindow;
  213.     DlgCreationWindow = 0;
  214.   }
  215.   if (!dialog)
  216.     return FALSE;
  217.  
  218.   //
  219.   // Handle all messages once thunked.
  220.   // Call the virtual DialogFunction() to handle specific messages
  221.   //
  222. #if defined(__WIN32__)
  223.   static DWORD version = ::GetVersion();
  224.   if (!(version & 0x80000000))
  225.     return dialog->DialogFunction(msg, wParam, lParam);
  226. #endif
  227.   TRY {
  228.     return dialog->DialogFunction(msg, wParam, lParam);
  229.   }
  230.   CATCH( (TXOwl& x) {
  231.     w->GetApplication()->SuspendThrow(x);
  232.   })
  233.   CATCH( (xalloc& x) {
  234.     w->GetApplication()->SuspendThrow(x);
  235.   })
  236.   CATCH( (xmsg& x) {
  237.     w->GetApplication()->SuspendThrow(x);
  238.   })
  239.   CATCH( (Bad_cast) {
  240.     w->GetApplication()->SuspendThrow(TApplication::xsBadCast);
  241.   })
  242.   CATCH( (Bad_typeid) {
  243.     w->GetApplication()->SuspendThrow(TApplication::xsBadTypeid);
  244.   })
  245.   CATCH( (...) {
  246.     w->GetApplication()->SuspendThrow(TApplication::xsUnknown);
  247.   })
  248.  
  249.   // When we're building small model, exceptions are disabled
  250.   // CATCH is defined as empty, so the only code is the TRY block,
  251.   // making this return unreachable
  252.   #pragma warn -rch
  253.   return TRUE;  // default value returned when exception caught
  254.   #pragma warn .rch
  255. }
  256.  
  257. static BOOL
  258. RegisterFails(TWindow* win, void*)
  259. {
  260.   return !win->Register();
  261. }
  262.  
  263. //
  264. // creates an MS-Windows modeless dialog and associates the modeless
  265. // dialog interface element with the TDialog
  266. //
  267. BOOL
  268. TDialog::Create()
  269. {
  270.   PRECONDITION(HWindow == 0);
  271.  
  272.   IsModal = FALSE;
  273.  
  274.   if (!Register())
  275.     THROW( TXWindow(this, IDS_CLASSREGISTERFAIL) );
  276.  
  277.   DlgCreationWindow = this;
  278.  
  279.   LoadAcceleratorTable();
  280.  
  281.   //
  282.   // register all the dialog's child objects (for custom control support)
  283.   //
  284.   if (FirstThat(RegisterFails))
  285.     THROW( TWindow::TXWindow(this, IDS_CHILDREGISTERFAIL) );
  286.  
  287.   HWindow = DoCreate();
  288.   GetApplication()->ResumeThrow();
  289.   if (!HWindow)
  290.     THROW( TWindow::TXWindow(this, IDS_WINDOWCREATEFAIL) );
  291.  
  292.   GetHWndState();
  293.   return TRUE;
  294. }
  295.  
  296. HWND
  297. TDialog::DoCreate()
  298. {
  299.   return CreateDialogParam(*GetModule(), Attr.Name, Parent? Parent->HWindow : 0,
  300.                            (DLGPROC)(FARPROC)StdDlgProcInstance, Attr.Param);
  301. }
  302.  
  303. //
  304. // creates an modal dialog and associates the modal dialog interface
  305. // element with the TDialog.  Registers all the dialog's child objects
  306. // (for custom control support).  If this registering fails, throws TXWindow
  307. // exception.  If the dialog fails to execute, throw a TXWindow exception.
  308. // Returns the return value from the dialog manager.
  309. //
  310. int
  311. TDialog::Execute()
  312. {
  313.   PRECONDITION(HWindow == 0);
  314.  
  315.   IsModal = TRUE;
  316.  
  317.   if (!Register())
  318.     THROW( TXWindow(this, IDS_CLASSREGISTERFAIL) );
  319.  
  320.   DlgCreationWindow = this;
  321.  
  322.   //
  323.   // register all the dialog's child objects (for custom control support)
  324.   //
  325.   if (FirstThat(RegisterFails))
  326.     THROW( TXWindow(0, IDS_CHILDREGISTERFAIL) );   // unspecified child window
  327.  
  328.   int retValue = DoExecute();
  329.   GetApplication()->ResumeThrow();
  330.  
  331.   //
  332.   // -1 if the function cannot create the dialog box
  333.   //
  334.   if (retValue == -1)
  335.     THROW( TXWindow(this, IDS_WINDOWEXECUTEFAIL) );
  336.  
  337.   return retValue;
  338. }
  339.  
  340. int
  341. TDialog::DoExecute()
  342. {
  343.   return DialogBoxParam(*GetModule(), Attr.Name, Parent ? Parent->HWindow : 0,
  344.                         (DLGPROC)(FARPROC)StdDlgProcInstance, Attr.Param);
  345. }
  346.  
  347. BOOL
  348. TDialog::PerformDlgInit()
  349. {
  350.   BOOL ok = TRUE;
  351.   if (Attr.Name) {
  352.     HRSRC hRes = GetModule()->FindResource(Attr.Name, RT_DLGINIT);
  353.     if (hRes) {
  354.       HGLOBAL hDat = GetModule()->LoadResource(hRes);
  355.       if (hDat) {
  356.         BYTE HUGE* hpRes = (BYTE HUGE*)::LockResource(hDat);
  357.         if (hpRes) {
  358.           while (ok && *hpRes) {
  359.             BYTE buff[4];
  360.  
  361.             buff[0] = *hpRes++;
  362.             buff[1] = *hpRes++;
  363.             UINT  nIDC = *((UINT FAR*)buff);
  364.  
  365.             buff[0] = *hpRes++;
  366.             buff[1] = *hpRes++;
  367.             UINT  nMsg = *((UINT FAR*)buff);
  368.  
  369.             buff[0] = *hpRes++;
  370.             buff[1] = *hpRes++;
  371.             buff[2] = *hpRes++;
  372.             buff[3] = *hpRes++;
  373.             DWORD dwLen = *((DWORD FAR*)buff);
  374.  
  375.             if (SendDlgItemMessage(nIDC, nMsg, 0, LPARAM(hpRes)) == -1)
  376.               ok = FALSE;
  377.             hpRes += dwLen;
  378.           }
  379.           #if !defined(__WIN32__)
  380.             ::UnlockResource(hDat);
  381.           #endif
  382.         }
  383.         #if !defined(__WIN32__)
  384.           ::FreeResource(hDat);
  385.         #endif
  386.         GetApplication()->ResumeThrow();
  387.       }
  388.     }
  389.   }
  390.   return ok;
  391. }
  392.  
  393. //
  394. // responds to an incoming WM_INITDIALOG message
  395. //
  396. // this message is sent after an MS-Windows dialog is created and before
  397. // the dialog is displayed
  398. //
  399. // calls SetupWindow() to perform setup for the dialog
  400. //
  401. BOOL
  402. TDialog::EvInitDialog(HWND /*hWndFocus*/)
  403. {
  404.   GetHWndState();
  405.   PerformDlgInit();
  406.   SetupWindow();
  407.   return TRUE;  // have Windows set focus to "hWndFocus"
  408. }
  409.  
  410. //
  411. // sets up the dialog box by calling setting up ctl3d if enabled, then
  412. // calling SetCaption() and then TWindow::SetupWindow()
  413. //
  414. // calling SetCaption() here allows us to override the dialog caption
  415. // (specified in the dialog resource) by setting Title prior to this point
  416. //
  417. void
  418. TDialog::SetupWindow()
  419. {
  420.   //
  421.   // If this app is using Ctl3d, tell it to explicitly subclass this dialog's
  422.   // controls (CTL3D_ALL). Its better to do this here than enable
  423.   // autosubclassing since that requires a CBT hook set all the time which
  424.   // slows the app considerably.
  425.   //
  426.   if (GetApplication()->Ctl3dEnabled()) {
  427.     static BOOL FAR PASCAL(*ctl3dSubclassDlg)(HWND, WORD) = 0;
  428.     if (!ctl3dSubclassDlg)
  429.      (FARPROC)ctl3dSubclassDlg = GetApplication()->GetCtl3dModule()->
  430.                                    GetProcAddress("Ctl3dSubclassDlg");
  431.     if (ctl3dSubclassDlg)
  432.       ctl3dSubclassDlg(*this, 0xFFFF);
  433.   }
  434.  
  435.   SetCaption(Title);
  436.   TWindow::SetupWindow();
  437. }
  438.  
  439. //
  440. // conditionally shuts down the dialog box
  441. //
  442. // if this is a modal dialog calls CanClose() and, if CanClose() returns TRUE,
  443. // transfers its data and shuts down, passing retValue (default IDCANCEL)
  444. //
  445. // calls TWindow::CloseWindow(retValue) if this is a modeless dialog
  446. //
  447. void
  448. TDialog::CloseWindow(int retValue)
  449. {
  450.   if (IsModal) {
  451.     if (CanClose()) {
  452.       TransferData(tdGetData);
  453.       Destroy(retValue);
  454.     }
  455.  
  456.   } else {
  457.     TWindow::CloseWindow(retValue);
  458.   }
  459. }
  460.  
  461. //
  462. // destroys the MS-Windows dialog associated with the TDialog
  463. //
  464. void
  465. TDialog::Destroy(int retValue)
  466. {
  467.   if (IsModal && HWindow) {
  468.     ForEach(DoEnableAutoCreate);
  469.     ::EndDialog(HWindow, retValue);
  470.  
  471.   } else {
  472.     TWindow::Destroy(retValue);
  473.   }
  474. }
  475.  
  476. //
  477. // set Dialog's Title data member and Caption. This is non-virtual, but is
  478. // always called with a TDialog or more specific pointer.
  479. //
  480. void
  481. TDialog::SetCaption(const char far* title)
  482. {
  483.   if (HIWORD(title) && LOWORD(title) != 0xFFFF)
  484.     TWindow::SetCaption(title);
  485. }
  486.  
  487. //
  488. // responds to an incoming notification message from a button with
  489. // an Id equal to IDOK
  490. //
  491. void
  492. TDialog::CmOk()
  493. {
  494.   CloseWindow(IDOK);
  495. }
  496.  
  497. //
  498. // responds to an incoming notification message from a button with
  499. // an Id equal to IDCANCEL. Unconditionally destroy the window.
  500. //
  501. void
  502. TDialog::CmCancel()
  503. {
  504.   Destroy(IDCANCEL);
  505. }
  506.  
  507. //
  508. // message response function for WM_CLOSE. Behave the same as a cancel
  509. //
  510. void
  511. TDialog::EvClose()
  512. {
  513.   CmCancel();
  514. }
  515.  
  516. #endif
  517. #if !defined(SECTION) || SECTION == 2
  518.  
  519. IMPLEMENT_STREAMABLE1(TDialog, TWindow);
  520.  
  521. //
  522. // reads an instance of TDialog from the passed ipstream
  523. //
  524. void*
  525. TDialog::Streamer::Read(ipstream& is, uint32 /*version*/) const
  526. {
  527.   ReadBaseObject((TWindow*)GetObject(), is);
  528.  
  529.   is >> (TResId&)GetObject()->Attr.Name;
  530.   is >> GetObject()->IsModal;
  531.   return GetObject();
  532. }
  533.  
  534. //
  535. // writes the TDialog to the passed opstream
  536. //
  537. void
  538. TDialog::Streamer::Write(opstream& os) const
  539. {
  540.   WriteBaseObject((TWindow*)GetObject(), os);
  541.  
  542.   os << TResId(GetObject()->Attr.Name);
  543.   os << GetObject()->IsModal;
  544. }
  545. #endif
  546.