|
|
//+----------------------------------------------------------------------------
//
// Windows NT Active Directory Property Page Sample
//
// The code contained in this source file is for demonstration purposes only.
// No warrantee is expressed or implied and Microsoft disclaims all liability
// for the consequenses of the use of this source code.
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: page.cxx
//
// Contents: CDsPropPage, the class that implements the sample property
// page.
//
// History: 8-Sep-97 Eric Brown created
// 24-Sep-98 " " revised to include notification object.
//
//-----------------------------------------------------------------------------
#include "page.h"
WCHAR wzSpendingLimit[] = L"spendingLimit";
//+----------------------------------------------------------------------------
//
// Member: CDsPropPage::CDsPropPage
//
//-----------------------------------------------------------------------------
CDsPropPage::CDsPropPage(HWND hNotifyObj) : m_hPage(NULL), m_pDsObj(NULL), m_fInInit(FALSE), m_fPageDirty(FALSE), m_pwzObjPathName(NULL), m_pwzObjClass(NULL), m_pwzRDName(NULL), m_hNotifyObj(hNotifyObj), m_pWritableAttrs(NULL), m_hrInit(S_OK) { }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPage::~CDsPropPage
//
// Notes: m_pWritableAttrs does not need to be freed. It refers to
// memory held by the notify object and freed when the notify
// object is destroyed.
//
//-----------------------------------------------------------------------------
CDsPropPage::~CDsPropPage() { if (m_pDsObj) { m_pDsObj->Release(); } if (m_pwzObjPathName) { delete m_pwzObjPathName; } if (m_pwzObjClass) { delete m_pwzObjClass; } if (m_pwzRDName) { delete m_pwzRDName; } }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::CreatePage
//
// Sysnopsis: Create the prop page
//
// Notes: if m_hrInit contains a failure code at this point, then an
// error page template could be substituted for the regular one.
//
//-----------------------------------------------------------------------------
HRESULT CDsPropPage::CreatePage(HPROPSHEETPAGE * phPage) { TCHAR szTitle[MAX_PATH]; if (!LoadString(g_hInstance, IDS_PAGE_TITLE, szTitle, MAX_PATH - 1)) { DWORD dwErr = GetLastError(); return HRESULT_FROM_WIN32(GetLastError()); } PROPSHEETPAGE psp;
psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_USECALLBACK | PSP_USETITLE; psp.pszTemplate = (LPCTSTR)IDD_SAMPLE_PAGE; psp.pfnDlgProc = StaticDlgProc; psp.pfnCallback = PageCallback; psp.pcRefParent = NULL; // do not set PSP_USEREFPARENT
psp.lParam = (LPARAM) this; psp.hInstance = g_hInstance; psp.pszTitle = L"Spending Limit";
*phPage = CreatePropertySheetPage(&psp);
if (*phPage == NULL) { return HRESULT_FROM_WIN32(GetLastError()); }
return S_OK; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::Init
//
// Sysnopsis: Initialize the page object. This is the second part of a two
// phase creation where operations that could fail are located.
//
//-----------------------------------------------------------------------------
HRESULT CDsPropPage::Init(PWSTR pwzObjName, PWSTR pwzClass) { //NTRAID#NTBUG9-572007-2002/03/10-jmessec If Init called multiple times, memory is leaked
//NTRAID#NTBUG9-572007-2002/03/10-jmessec If second allocation fails, m_pwszObjPathName points to an uninitialized buffer
m_pwzObjPathName = new WCHAR[wcslen(pwzObjName) + 1]; if (m_pwzObjPathName == NULL ) { return E_OUTOFMEMORY; }
m_pwzObjClass = new WCHAR[wcslen(pwzClass) + 1]; if (m_pwzObjClass == NULL) { return E_OUTOFMEMORY; } wcscpy(m_pwzObjPathName, pwzObjName); wcscpy(m_pwzObjClass, pwzClass);
//
// NOTIFY_OBJ
// Contact the notification object for the initialization info.
//
ADSPROPINITPARAMS InitParams = {0};
InitParams.dwSize = sizeof (ADSPROPINITPARAMS); if (!ADsPropGetInitInfo(m_hNotifyObj, &InitParams)) { m_hrInit = E_FAIL; return E_FAIL; }
if (FAILED(InitParams.hr)) { m_hrInit = InitParams.hr; return m_hrInit; }
m_pwzRDName = new WCHAR[wcslen(InitParams.pwzCN) + 1];
if (m_pwzRDName == NULL) { m_hrInit = E_OUTOFMEMORY; return E_OUTOFMEMORY; }
m_pDsObj = InitParams.pDsObj; m_pDsObj->AddRef();
m_pWritableAttrs = InitParams.pWritableAttrs;
return S_OK; }
//+----------------------------------------------------------------------------
//
// Method: StaticDlgProc
//
// Sysnopsis: static dialog proc
//
//-----------------------------------------------------------------------------
BOOL CALLBACK StaticDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CDsPropPage * pPage = (CDsPropPage *)GetWindowLongPtr(hDlg, DWLP_USER);
if (uMsg == WM_INITDIALOG) { LPPROPSHEETPAGE ppsp = (LPPROPSHEETPAGE)lParam;
pPage = (CDsPropPage *) ppsp->lParam; pPage->m_hPage = hDlg;
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pPage); }
switch (uMsg) { case WM_INITDIALOG: pPage->m_fInInit = TRUE; pPage->OnInitDialog(lParam); pPage->m_fInInit = FALSE; return TRUE;
case WM_COMMAND: return pPage->OnCommand(LOWORD(wParam),(HWND)lParam, HIWORD(wParam));
case WM_NOTIFY: return pPage->OnNotify(uMsg, wParam, lParam); }
return FALSE; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::OnInitDialog
//
// Sysnopsis: Handles dialog initialization messages
//
//-----------------------------------------------------------------------------
LRESULT CDsPropPage::OnInitDialog(LPARAM lParam) { PADS_ATTR_INFO pAttrs = NULL; DWORD cAttrs = 0; HRESULT hr = S_OK;
//
// NOTIFY_OBJ
// Send the notification object the page's window handle.
//
if (!ADsPropSetHwnd(m_hNotifyObj, m_hPage)) { m_pWritableAttrs = NULL; }
//
// Disable the edit control if the user does not have write permission on
// the attribute.
//
if (!ADsPropCheckIfWritable(wzSpendingLimit, m_pWritableAttrs)) { EnableWindow(GetDlgItem (m_hPage, IDC_SPENDING_EDIT), FALSE); }
//
// Get the attribute value.
//
PWSTR rgpwzAttrNames[] = {wzSpendingLimit};
hr = m_pDsObj->GetObjectAttributes(rgpwzAttrNames, 1, &pAttrs, &cAttrs);
if (FAILED(hr)) { // Display an error.
return TRUE; }
if (cAttrs == 1 && pAttrs->dwNumValues > 0) { // Display the value.
//
SetWindowText(GetDlgItem (m_hPage, IDC_SPENDING_EDIT), pAttrs->pADsValues->CaseIgnoreString); }
return TRUE; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::OnNotify
//
// Sysnopsis: Handles notification messages
//
//-----------------------------------------------------------------------------
LRESULT CDsPropPage::OnNotify(UINT uMessage, WPARAM wParam, LPARAM lParam) { switch (((LPNMHDR)lParam)->code) { case PSN_APPLY:
if (!m_fPageDirty) { return PSNRET_NOERROR; } { LRESULT lResult = OnApply(); // Store the result into the dialog
SetWindowLongPtr(m_hPage, DWLP_MSGRESULT, lResult); } return TRUE;
case PSN_RESET: return FALSE; // allow the property sheet to be destroyed.
case PSN_SETACTIVE: return OnPSNSetActive(lParam);
case PSN_KILLACTIVE: return OnPSNKillActive(lParam); }
return TRUE; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::OnCommand
//
// Sysnopsis: Handles the WM_COMMAND message
//
//-----------------------------------------------------------------------------
LRESULT CDsPropPage::OnCommand(int id, HWND hwndCtl, UINT codeNotify) { if ((codeNotify == EN_CHANGE) && !m_fInInit) { SetDirty(); } if ((codeNotify == BN_CLICKED) && (id == IDCANCEL)) { //
// Pressing ESC in a multi-line edit control results in this
// WM_COMMAND being sent. Pass it on to the parent (the sheet proc) to
// close the sheet.
//
PostMessage(GetParent(m_hPage), WM_COMMAND, MAKEWPARAM(id, codeNotify), (LPARAM)hwndCtl); } return 0; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::OnApply
//
// Sysnopsis: Handles the PSN_APPLY notification message
//
//-----------------------------------------------------------------------------
LRESULT CDsPropPage::OnApply() { HRESULT hr = S_OK; DWORD cModified; ADS_ATTR_INFO aAttrs[1]; PADS_ATTR_INFO pAttrs = aAttrs; WCHAR wzEdit[MAX_PATH]; UINT cch; ADSVALUE Value; PWSTR rgpwzAttrNames[] = {wzSpendingLimit};
cch = GetDlgItemText(m_hPage, IDC_SPENDING_EDIT, wzEdit, MAX_PATH);
pAttrs[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING; pAttrs[0].pszAttrName = rgpwzAttrNames[0];
if (cch > 0) { Value.dwType = ADSTYPE_CASE_IGNORE_STRING; Value.CaseIgnoreString = wzEdit; pAttrs[0].pADsValues = &Value; pAttrs[0].dwNumValues = 1; pAttrs[0].dwControlCode = ADS_ATTR_UPDATE; } else { pAttrs[0].pADsValues = NULL; pAttrs[0].dwNumValues = 0; pAttrs[0].dwControlCode = ADS_ATTR_CLEAR; }
//
// Write the changes.
//
hr = m_pDsObj->SetObjectAttributes(pAttrs, 1, &cModified);
//
// NOTIFY_OBJ
// Signal the change notification. Note that the notify-apply
// message must be sent even if the page is not dirty so that the
// notify ref-counting will properly decrement.
//
SendMessage(m_hNotifyObj, WM_ADSPROP_NOTIFY_APPLY, TRUE, 0);
m_fPageDirty = FALSE;
return FALSE; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::OnPSNSetActive
//
// Sysnopsis: Page activation event.
//
//-----------------------------------------------------------------------------
LRESULT CDsPropPage::OnPSNSetActive(LPARAM lParam) { SetWindowLongPtr(m_hPage, DWLP_MSGRESULT, 0); return TRUE; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::OnPSNKillActive
//
// Sysnopsis: Page deactivation event (when other pages cover this one).
//
//-----------------------------------------------------------------------------
LRESULT CDsPropPage::OnPSNKillActive(LPARAM lParam) { SetWindowLongPtr(m_hPage, DWLP_MSGRESULT, 0); return TRUE; }
//+----------------------------------------------------------------------------
//
// Method: CDsPropPage::PageCallback
//
// Sysnopsis: Callback used to free the CDsPropPage object when the
// property sheet has been destroyed.
//
//-----------------------------------------------------------------------------
UINT CALLBACK CDsPropPage::PageCallback(HWND hDlg, UINT uMsg, LPPROPSHEETPAGE ppsp) {
if (uMsg == PSPCB_RELEASE) { //
// Determine instance that invoked this static function
//
CDsPropPage * pPage = (CDsPropPage *) ppsp->lParam;
if (IsWindow(pPage->m_hNotifyObj)) { //
// NOTIFY_OBJ
// Tell the notification object to shut down.
//
SendMessage(pPage->m_hNotifyObj, WM_ADSPROP_NOTIFY_EXIT, 0, 0); }
delete pPage;
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL); }
return TRUE; }
|