[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1165
  • Last Modified:

ActiveX Property Page OnOK

Hi,

On My property Page, I am saving a few fields to a ini file.  When the user hits the Ok button, I want to check that each field has a value, if all the fields do NOT have a value I want to keep them on the dialog and prompt them with a message saying all fields are required.  how do i go about this?? Thanks,
0
cophi
Asked:
cophi
  • 10
  • 9
  • 8
  • +2
1 Solution
 
mahesh1402Commented:
You can simulate clicking one of Property Sheet buttons from within your code by calling the CPropertySheet's PressButton() function from your derived property sheet object. The PressButton() function can be passed PSBTN_OK, PSBTN_CANCEL, or PSBTN_APPLYNOW to simulate the OK, Cancel, or Apply button, respectively. This function passes a PSM_PRESSBUTTON message to the property sheet.

Also After the property sheet's OK button is clicked, an OnOK() virtual function is called for each of those property pages that have been displayed during the lifetime of the property sheet. Your property pages should override OnOK() to perform any OK handling specific to that page (and that page only). After all of the OnOK() functions have been called and returned in each of the property pages, the property sheet will be closed.

-MAHESH
0
 
cophiAuthor Commented:
Hi MAHESH,

You keep talking about property sheets but I'm asking a question about property pages.  The Property Page has an OnOK() virtual function, but its just a void.  If I had code in there to do some checking, how would I let it go back to the dialog.  The onOK makes the dialog go away.

class CAtxPropPage : public COlePropertyPage
{
      DECLARE_DYNCREATE(CAtxPropPage)
      DECLARE_OLECREATE_EX(CAtxPropPage)

// Constructor
public:
      CAtxPropPage();
0
 
mahesh1402Commented:
>>The onOK makes the dialog go away.

So do you want to trap event as soon as property value is changed ? if so have a look at DISP_PROPERTY_NOTIFY  

refer :
http://www.codeguru.com/cpp/com-tech/activex/controls/article.php/c5517/

-MAHESH
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
cophiAuthor Commented:
Basically what i want to do is, if I have all these fields on my dialog that are required.  Whats the best way of forcing them to be required.  Where do I do this at on the property page dialog?  
0
 
mahesh1402Commented:
cant you add a command handler in your property page message map for OK button ?

e.g in your proppage.cpp file

BEGIN_MESSAGE_MAP(CPropPage, COlePropertyPage)
                                                         <-- handler for OK button
ENDMESSAGE_MAP()

-MAHESH
0
 
AndyAinscowCommented:
pseudo code for a property sheet - one page doesn't require the loop for each page in the sheet (simpler)

CMySheet::OnOK()
{
  bool bOK = true;
  for(each page)
  {
    check contents of variables
    if(contents NOT OK)  bOK = false;   //At least one page has variables not correct - flag to stop
  }
  if(bOK)
    {
    CPropertySheet::OnOK();   //call base class to allow the default behaviour - close sheet
     return;
    }
}
0
 
cophiAuthor Commented:
haha alright guys, i'm getting really confused about these propertysheets.  the default implementation is cpropertypage.  how would I do this for propertypage
0
 
DanRollinsCommented:
I believe that the propertysheet may be outside of your control -- it is hosted by the container (I think).

I'm almost certain that what you are looking for is here:
    CPropertyPage::OnKillActive
    http://msdn2.microsoft.com/zh-tw/library/2122ct0z.aspx

Just override that fn and do the validation.  If the data is no good, return FALSE.  You can add some extra stuff like popping up a message box indicating which imnput was wrong and why, and most programmers will do that.

-- Dan
0
 
puranik_pCommented:
You can make your propery page to work like dialog by proving a dialog template to it.


e.g If u bave a class CPropPage derived from COleCtrl.
Then u can override the OnCreate function like this if you want to place List control on it.

int CPropPage::OnCreate(LPCREATESTRUCT lpCreateStruct)
{


      if (COlePropertyPage::OnCreate(lpCreateStruct) == -1)
            return -1;

      //create list control...
      DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_TABSTOP | LVS_REPORT;


               CListCtrlEx m_ListEx;  //write a class CListCtrlEx derived from CListCtrl.
      BOOL bResult = m_ListEx.Create(dwStyle, CRect(0, 35, 945, 430), this, REPORTS_LISTCTRL_ID);
   
              <same way you can attache dialog instead of list.          
      CDlg      dlg; //write a CDlg  derived from CDialog.
      dlg.Create(.....)     // After this you can handle all you events in CDlg class >


      return 0;
}

0
 
mahesh1402Commented:
Cophie,
Why not to Override OnDestroy() of your property page .......

void CSamplePropPage::OnDestroy()
{

if(..) // check control values here
 ....
 ....
COlePropertyPage::OnDestroy();

}

Just goto your proppage.cpp invoke class wizard using Ctrl+W and double click WM_DESTROY to edit code.

-MAHESH
0
 
cophiAuthor Commented:
MAHESH,

So I've overrided OnDestroy(), now what do I do when I check the values, I find that one is empty, and I want the dialog to stay up, because if I let it finish its routine the dialog goes away.

DanRollins ,

OnKillActive is not a valid event
0
 
mahesh1402Commented:
>>I find that one is empty, and I want the dialog to stay up, because if I let it finish its routine the dialog goes away.

Just DO NOT CALL base class OnDestroy() ie. just return dont call 'COlePropertyPage::OnDestroy();'

-MAHESH
0
 
mahesh1402Commented:
i.e. somthing like

void CSamplePropPage::OnDestroy()
{

if(..) // check control values here
{
// Display Alert
 return;
}

COlePropertyPage::OnDestroy();

}

-MAHESH
0
 
mahesh1402Commented:
I doubt this will work or not as its called on destroy.......
0
 
cophiAuthor Commented:
Yeah it doesn't work...
0
 
mahesh1402Commented:
In your resource editor how may property page dialogs do you have ?. cant you locate your resources there ??

-MAHESH
0
 
DanRollinsCommented:
>> OnKillActive is not a valid event...
No, obviously.  It is a member of the CPropertyPage base class that can be overridden...
However, I now see that you are working with COleProperyPage-derived object.

In that case, I suggest you look for and trap...
 
     PSN_KILLACTIVE Notification
     http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/propsheet/notifications/psn_killactive.asp

It comes as a WM_NOTIFY message to each page.  Return FALSE if all of the input data is fine, else return TRUE to prevent the user from leaving the page (or in a one-page sheet, OKing the dialog).  

That'll fix you right up.

-- Dan
0
 
AndyAinscowCommented:
Extract from question - When the user hits the Ok button...


Have you looked at my comment ?  
0
 
DanRollinsCommented:
I think since cophi is working an an ActiveX, he is working with COlePropertyPage(see http:#16606557) so I don't think can work with or derive from CPropertySheet -- and thus he cannot provide an override for OnOK()

On the other hand, it appears that WM_NOTIFY / PSN_KILLACTIVE message will be sent to COlePropertyPage from the parent sheet.  A handler for PSN_KILLACTIVE can be used to validate the data and prevent closure.

At least in CPropertyPage, it is called when the user pressed the OK button in the parent propertysheet.  It is also called when there are multiple pages and the user switches pages, but I think we are looking at a one-page sheet here.
0
 
DanRollinsCommented:
According to this, you can also override UpdateData() or DoDataEchange to catch OK or Apply:

   Catching Apply and OK in ActiveX Properties Dialog
   http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_10040439.html

Here's another good PAQ:
   Invoking the properties dialog
   http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_10364679.html

This link describes the DoDataExchange option, and provides excellent source code examples and explanations:
     "Special" validation on a COlePropertyPage?
      http://groups.google.com/group/microsoft.public.vc.mfcole/browse_frm/thread/701fdbcd0fae5ec9

If you need any help implementing any of this, just speak say so.

-- Dan
0
 
AndyAinscowCommented:
He specifically says in response to a button press in his question.  I am saying validate in the button press handler and only close if the data is valid.
0
 
DanRollinsCommented:
As I stated, the OK button is on the SHEET, not the PAGE.  

If you only control what happens on the PropertyPage, it is not so easy to intercept the OK button of the PropertySheet.  I don't know how to make it more clear.  If you are deriving from COlePropertyPage, then nothing you override in that class will have any effect on what happens with the OK button because the WM_COMMAND message for the OK button is never sent to the PropertyPage.  It is sent to the parent window.  

When the OK button is clicked in the SHEET, the PAGE gets only a WM_NOTIFY message.
0
 
AndyAinscowCommented:
Dan - this is the start of my comment:

pseudo code for a property sheet - one page doesn't require the loop for each page in the sheet (simpler)

CMySheet::OnOK()
{
  bool bOK = true;
  for(each page)
....

I understand PERFECTLY that he talks about the button on the sheet - which is why I suggested what I did.  I have not suggested handling the button press in the page directly.
0
 
DanRollinsCommented:
And my point is that cophi is not working with a standard CPropertyPage and is UNABLE to access or derive from the parent sheet -- because he writing an

     ActiveX Control

and he only has access to the

     COlePropertyPage.  
       ^^^
The sheet is hosted by the underlying ActiveX support.
0
 
AndyAinscowCommented:
I think cophi ought to say is he wanting to know about a PropertySheet/PropertyPage he has constructed and displayed or an OlePropertyPage that the system is showing for him.
0
 
DanRollinsCommented:
AndyAinscow... He has, quite clearly: http:#16606557
0
 
AndyAinscowCommented:
All that says is COlePropertyPage, it does NOT tell us how it is being constructed/displayed.
0
 
AndyAinscowCommented:
Dan - consider the following.
ActiveX control that displays a propertysheet with pages on it and buttons on the sheet.  The person coding the control has the property sheet under their control.
0
 
DanRollinsCommented:
If so, I don't know how.  All he the coder does is provide one or more pages and the container supplies the parent dialog (it looks like a standard dialog with a SysTabControl32 embedded to handle the pages provided by the coder).

 If you can provide an example that lets the coder somehow derive from that container-supplied parent to allow him to override any of it's functionality, that workis in the context of an ActiveX control and a COlePropertyPage, then I'll apologize to you and as a bonus, the asker's question will be answered.  Here is a good place to start your research:
     http://msdn.microsoft.com/library/en-us/vccore98/HTML/_core_activex_controls.3a_.property_pages.asp

It may be possible to subclass that container-supplied parent dialog, but there is no point.  Just handle the UpdateData, DoDataExchange, or handle the PSN_KILLACTIVE notification in the object that you DO have control over

-- Dan
0
 
DanRollinsCommented:
cophi,
It would be nice to hear from you.  Are you listening?  Are you still confused?  Have you tried any of my suggestions?  Do you need to know how to add a notification handler to your CAtxPropPage object?  Please respond.  Thanks!
0
 
cophiAuthor Commented:
Sorry, it was the weekend.  I am on a property page like I said before.  I'm going to try PSN_KILLACTIVE Notification.

class CAtxPropPage : public COlePropertyPage
{
     DECLARE_DYNCREATE(CAtxPropPage)
     DECLARE_OLECREATE_EX(CAtxPropPage)

// Constructor
public:
     CAtxPropPage();

0
 
cophiAuthor Commented:
Ok Dan,

I went with a different approach.  I wanted to override the UpdateData, because it made more sense to me.  The only problem is I don't see the UpdateData being called.  I have this code...

BOOL CatxPropPage::UpdateData(BOOL bSaveAndValidate)
{
      int i = 0;  // <-- BREAKPOINT HERE

      return(true);
}

class CatxPropPage : public COlePropertyPage
{
      DECLARE_DYNCREATE(CatxPropPage)
      DECLARE_OLECREATE_EX(CatxPropPage)

// Constructor
public:
      CatxPropPage();

// Dialog Data
      enum { IDD = IDD_PROPPAGE_ATX };

// Implementation
protected:
      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
      virtual BOOL UpdateData(BOOL bSaveAndValidate);
0
 
DanRollinsCommented:
It looks like the base class COlePropertyPage only calls UpdataData() if there are one or more properties to update.   If you have no yet done so, add a property to the activeX control and then follow the steps here:
     http://msdn.microsoft.com/library/en-us/vctutor98/HTML/_gs_linking_controls_with_properties.asp
to add a control (such as a checkbox or edit control) to the dialog and associate that control with a member variable to the propertypage object.  The wizard will add some lines to your DoDataExchange() function.

If ther are already some items DDP or DDX lines in DoDataExchange(), then try using an AfxMessageBox rather than a breakpoint to indicate that the code gets executed.

-- Dan
0
 
AndyAinscowCommented:
According to the help files returning FALSE from the UpdateData should stop the default behaviour - ie the closing of the page (sheet).


The default implementation of CDialog::OnOK calls this member function with bSaveAndValidate set to TRUE to retrieve the data, and if successful, will close the dialog box. (If the Cancel button is clicked in the dialog box, the dialog box is closed without the data being retrieved.)

Maybe just try a return false from the UpdateData you override (when SAVING else it probably wont appear) and see if you need to use the task manager to kill the page (sheet).
0
 
AndyAinscowCommented:
Dan, this might explain some of my confusion (I'm not trying to be foolish/destructive in this thread).  
http://www.experts-exchange.com/Programming/Programming_Languages/MFC/Q_21836321.html

start of question - I have a custom active X.  On that property page I've added 3 CEdit controls...
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 10
  • 9
  • 8
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now