|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: acuictl.cpp
//
// Contents: Authenticode Default UI controls
//
// History: 12-May-97 kirtd Created
//
//----------------------------------------------------------------------------
#include <stdpch.h>
#include <richedit.h>
#include "secauth.h"
IACUIControl::IACUIControl(CInvokeInfoHelper& riih) : m_riih( riih ), m_hrInvokeResult( TRUST_E_SUBJECT_NOT_TRUSTED ) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED;
m_pszCopyActionText = NULL; m_pszCopyActionTextNoTS = NULL; m_pszCopyActionTextNotSigned = NULL;
if ((riih.ProviderData()) && (riih.ProviderData()->psPfns) && (riih.ProviderData()->psPfns->psUIpfns) && (riih.ProviderData()->psPfns->psUIpfns->psUIData)) { if (_ISINSTRUCT(CRYPT_PROVUI_DATA, riih.ProviderData()->psPfns->psUIpfns->psUIData->cbStruct, pCopyActionTextNotSigned)) { this->LoadActionText(&m_pszCopyActionText, riih.ProviderData()->psPfns->psUIpfns->psUIData->pCopyActionText, IDS_ACTIONSIGNED); this->LoadActionText(&m_pszCopyActionTextNoTS, riih.ProviderData()->psPfns->psUIpfns->psUIData->pCopyActionTextNoTS, IDS_ACTIONSIGNED_NODATE); this->LoadActionText(&m_pszCopyActionTextNotSigned, riih.ProviderData()->psPfns->psUIpfns->psUIData->pCopyActionTextNotSigned, IDS_ACTIONNOTSIGNED); } }
if (!(m_pszCopyActionText)) { this->LoadActionText(&m_pszCopyActionText, NULL, IDS_ACTIONSIGNED); }
if (!(m_pszCopyActionTextNoTS)) { this->LoadActionText(&m_pszCopyActionTextNoTS, NULL, IDS_ACTIONSIGNED_NODATE); }
if (!(m_pszCopyActionTextNotSigned)) { this->LoadActionText(&m_pszCopyActionTextNotSigned, NULL, IDS_ACTIONNOTSIGNED); } }
void IACUIControl::LoadActionText(WCHAR **ppszRet, WCHAR *pwszIn, DWORD dwDefId) { WCHAR sz[MAX_PATH];
*ppszRet = NULL; sz[0] = NULL;
if ((pwszIn) && (*pwszIn)) { sz[0] = NULL; if (wcslen(pwszIn) < MAX_PATH) { wcscpy(&sz[0], pwszIn); }
if (sz[0]) { if (*ppszRet = new WCHAR[wcslen(&sz[0]) + 1]) { wcscpy(*ppszRet, &sz[0]); } }
}
if (!(sz[0])) { sz[0] = NULL; LoadStringU(g_hModule, dwDefId, &sz[0], MAX_PATH);
if (sz[0]) { if (*ppszRet = new WCHAR[wcslen(&sz[0]) + 1]) { wcscpy(*ppszRet, &sz[0]); } } } }
IACUIControl::~IACUIControl () { DELETE_OBJECT(m_pszCopyActionText); DELETE_OBJECT(m_pszCopyActionTextNoTS); DELETE_OBJECT(m_pszCopyActionTextNotSigned); }
void IACUIControl::SetupButtons(HWND hWnd) { char sz[MAX_PATH];
if ((m_riih.ProviderData()) && (m_riih.ProviderData()->psPfns) && (m_riih.ProviderData()->psPfns->psUIpfns) && (m_riih.ProviderData()->psPfns->psUIpfns->psUIData)) { if (m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pYesButtonText) { if (!(m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pYesButtonText[0])) { ShowWindow(GetDlgItem(hWnd, IDYES), SW_HIDE); } else { SetWindowTextU(GetDlgItem(hWnd, IDYES), m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pYesButtonText); } }
if (m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pNoButtonText) { if (!(m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pNoButtonText[0])) { ShowWindow(GetDlgItem(hWnd, IDNO), SW_HIDE); } else { SetWindowTextU(GetDlgItem(hWnd, IDNO), m_riih.ProviderData()->psPfns->psUIpfns->psUIData->pNoButtonText); } } } }
//+---------------------------------------------------------------------------
//
// Member: IACUIControl::OnUIMessage, public
//
// Synopsis: responds to UI messages
//
// Arguments: [hwnd] -- window
// [uMsg] -- message id
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if message processing should continue, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL IACUIControl::OnUIMessage ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_INITDIALOG: { BOOL fReturn; HICON hIcon;
fReturn = OnInitDialog(hwnd, wParam, lParam);
ACUICenterWindow(hwnd);
// hIcon = LoadIcon((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDI_LOCK));
// dwOrigIcon = SetClassLongPtr(hwnd, GCLP_HICON,
// (LONG_PTR)LoadIcon((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
// MAKEINTRESOURCE(IDI_LOCK)));
// PostMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
// PostMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
return( fReturn ); } break;
case WM_COMMAND: { WORD wNotifyCode = HIWORD(wParam); WORD wId = LOWORD(wParam); HWND hwndControl = (HWND)lParam;
if ( wNotifyCode == BN_CLICKED ) { if ( wId == IDYES ) { return( OnYes(hwnd) ); } else if ( wId == IDNO ) { return( OnNo(hwnd) ); } else if ( wId == IDMORE ) { return( OnMore(hwnd) ); } }
return( FALSE ); } break;
case WM_CLOSE: return( OnNo(hwnd) ); break;
default: return( FALSE ); }
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::CVerifiedTrustUI, public
//
// Synopsis: Constructor
//
// Arguments: [riih] -- invoke info helper reference
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CVerifiedTrustUI::CVerifiedTrustUI (CInvokeInfoHelper& riih, HRESULT& rhr) : IACUIControl( riih ), m_pszInstallAndRun( NULL ), m_pszAuthenticity( NULL ), m_pszCaution( NULL ), m_pszPersonalTrust( NULL ) { DWORD_PTR aMessageArgument[3];
//
// Initialize the hot-link subclass data
//
m_lsdPublisher.uId = IDC_PUBLISHER; m_lsdPublisher.hwndParent = NULL; m_lsdPublisher.wpPrev = (WNDPROC)NULL; m_lsdPublisher.pvData = (LPVOID)&riih; m_lsdPublisher.uToolTipText = IDS_CLICKHEREFORCERT;
m_lsdOpusInfo.uId = IDC_INSTALLANDRUN; m_lsdOpusInfo.hwndParent = NULL; m_lsdOpusInfo.wpPrev = (WNDPROC)NULL; m_lsdOpusInfo.pvData = &riih; m_lsdOpusInfo.uToolTipText = (DWORD_PTR)riih.ControlWebPage();
m_lsdCA.uId = IDC_AUTHENTICITY; m_lsdCA.hwndParent = NULL; m_lsdCA.wpPrev = (WNDPROC)NULL; m_lsdCA.pvData = &riih; m_lsdCA.uToolTipText = (DWORD_PTR)riih.CAWebPage(); // IDS_CLICKHEREFORCAINFO;
m_lsdAdvanced.uId = IDC_ADVANCED; m_lsdAdvanced.hwndParent = NULL; m_lsdAdvanced.wpPrev = (WNDPROC)NULL; m_lsdAdvanced.pvData = &riih; m_lsdAdvanced.uToolTipText = IDS_CLICKHEREFORADVANCED;
//
// Format the install and run string
//
aMessageArgument[2] = NULL;
if (m_riih.CertTimestamp()) { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionText; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = (DWORD_PTR)m_riih.CertTimestamp(); } else { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionTextNoTS; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = NULL; }
rhr = FormatACUIResourceString(0, aMessageArgument, &m_pszInstallAndRun);
//
// Format the authenticity string
//
if ( rhr == S_OK ) { aMessageArgument[0] = (DWORD_PTR)m_riih.PublisherCertIssuer();
rhr = FormatACUIResourceString( IDS_AUTHENTICITY, aMessageArgument, &m_pszAuthenticity ); }
//
// Get the publisher as a message argument
//
aMessageArgument[0] = (DWORD_PTR)m_riih.Publisher();
//
// Format the caution string
//
if ( rhr == S_OK ) { rhr = FormatACUIResourceString( IDS_CAUTION, aMessageArgument, &m_pszCaution ); }
//
// Format the personal trust string
//
if ( rhr == S_OK ) { rhr = FormatACUIResourceString( IDS_PERSONALTRUST, aMessageArgument, &m_pszPersonalTrust ); } }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::~CVerifiedTrustUI, public
//
// Synopsis: Destructor
//
// Arguments: (none)
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CVerifiedTrustUI::~CVerifiedTrustUI () { DELETE_OBJECT(m_pszInstallAndRun); DELETE_OBJECT(m_pszAuthenticity); DELETE_OBJECT(m_pszCaution); DELETE_OBJECT(m_pszPersonalTrust); }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::InvokeUI, public
//
// Synopsis: invoke the UI
//
// Arguments: [hDisplay] -- parent window
//
// Returns: S_OK, user trusts the subject
// TRUST_E_SUBJECT_NOT_TRUSTED, user does NOT trust the subject
// Any other valid HRESULT
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT CVerifiedTrustUI::InvokeUI (HWND hDisplay) { //
// Bring up the dialog
//
if ( DialogBoxParamU( g_hModule, (LPWSTR) MAKEINTRESOURCE(IDD_DIALOG1_VERIFIED), hDisplay, ACUIMessageProc, (LPARAM)this ) == -1 ) { return( HRESULT_FROM_WIN32(GetLastError()) ); }
//
// The result has been stored as a member
//
return( m_hrInvokeResult ); }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::OnInitDialog, public
//
// Synopsis: dialog initialization
//
// Arguments: [hwnd] -- dialog window
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if successful init, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CVerifiedTrustUI::OnInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam) { WCHAR psz[MAX_LOADSTRING_BUFFER]; HWND hControl; int deltavpos = 0; int deltaheight; int bmptosep; int septodlg; int savevpos; int hkcharpos; RECT rect;
//
// Setup the publisher link subclass data parent window
//
m_lsdPublisher.hwndParent = hwnd; m_lsdOpusInfo.hwndParent = hwnd; m_lsdCA.hwndParent = hwnd; m_lsdAdvanced.hwndParent = hwnd;
//
// Render the install and run string
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_INSTALLANDRUN, IDC_PUBLISHER, m_pszInstallAndRun, deltavpos, (m_riih.ControlWebPage()) ? TRUE : FALSE, (WNDPROC)ACUILinkSubclass, &m_lsdOpusInfo, 0, m_riih.Subject());
//
// Render the publisher, give it a "link" look and feel if it is a known
// publisher
//
//
// if there was a test cert in the chain, add it to the text...
//
if (m_riih.TestCertInChain()) { WCHAR *pszCombine;
pszCombine = new WCHAR[wcslen(m_riih.Publisher()) + wcslen(m_riih.TestCertInChain()) + 3];
if (pszCombine != NULL) { wcscpy(pszCombine, m_riih.Publisher()); wcscat(pszCombine, L"\r\n"); wcscat(pszCombine, m_riih.TestCertInChain());
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PUBLISHER, IDC_AUTHENTICITY, pszCombine, deltavpos, m_riih.IsKnownPublisher() && m_riih.IsCertViewPropertiesAvailable(), (WNDPROC)ACUILinkSubclass, &m_lsdPublisher, 0, NULL );
delete[] pszCombine; }
if (LoadStringU(g_hModule, IDS_TESTCERTTITLE, psz, MAX_LOADSTRING_BUFFER) != 0) { int wtlen;
wtlen = wcslen(psz) + GetWindowTextLength(hwnd); pszCombine = new WCHAR[wtlen + 1];
if (pszCombine != NULL) { #if (0) // DSIE: Wrong buffer length specified. We don't have wtlen + 1, instead,
// we only have GetWindowTextLength(hwnd) + 1.
GetWindowTextU(hwnd, pszCombine, wtlen + 1); #else
GetWindowTextU(hwnd, pszCombine, GetWindowTextLength(hwnd) + 1); #endif
wcscat(pszCombine, psz); SetWindowTextU(hwnd, pszCombine);
delete[] pszCombine; } } } else { deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PUBLISHER, IDC_AUTHENTICITY, m_riih.Publisher(), deltavpos, m_riih.IsKnownPublisher() && m_riih.IsCertViewPropertiesAvailable(), (WNDPROC)ACUILinkSubclass, &m_lsdPublisher, 0, NULL ); }
//
// Render the authenticity statement
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_AUTHENTICITY, IDC_CAUTION, m_pszAuthenticity, deltavpos, (m_riih.CAWebPage()) ? TRUE : FALSE, (WNDPROC)ACUILinkSubclass, &m_lsdCA, 0, m_riih.PublisherCertIssuer());
//
// Render the caution statement
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_CAUTION, IDC_ADVANCED, m_pszCaution, deltavpos, FALSE, NULL, NULL, 0, NULL );
//
// Render the advanced string
//
if ((m_riih.AdvancedLink()) && (m_riih.ProviderData()->psPfns->psUIpfns->pfnOnAdvancedClick)) { deltavpos = RenderACUIStringToEditControl( hwnd, IDC_ADVANCED, IDC_PERSONALTRUST, m_riih.AdvancedLink(), deltavpos, TRUE, (WNDPROC)ACUILinkSubclass, &m_lsdAdvanced, 0, NULL ); } else { ShowWindow(GetDlgItem(hwnd, IDC_ADVANCED), SW_HIDE); }
//
// Calculate the distances from the bottom of the bitmap to the top
// of the separator and from the bottom of the separator to the bottom
// of the dialog
//
bmptosep = CalculateControlVerticalDistance( hwnd, IDC_VERBMP, IDC_SEPARATORLINE );
septodlg = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE );
//
// Rebase the check box and render the personal trust statement or hide
// them the publisher is not known
//
if ( m_riih.IsKnownPublisher() == TRUE ) { hControl = GetDlgItem(hwnd, IDC_PTCHECK);
RebaseControlVertical( hwnd, hControl, NULL, FALSE, deltavpos, 0, bmptosep, &deltaheight );
assert( deltaheight == 0 );
//
// Find the hotkey character position for the personal trust
// check box
//
#if (0) //DSIE: Bug 34325
hkcharpos = GetHotKeyCharPosition(GetDlgItem(hwnd, IDC_PTCHECK)); #else
hkcharpos = GetHotKeyCharPositionFromString(m_pszPersonalTrust); #endif
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PERSONALTRUST, IDC_SEPARATORLINE, m_pszPersonalTrust, deltavpos, FALSE, NULL, NULL, bmptosep, NULL );
if ( hkcharpos != 0 ) { FormatHotKeyOnEditControl( GetDlgItem(hwnd, IDC_PERSONALTRUST), hkcharpos ); } } else { ShowWindow(GetDlgItem(hwnd, IDC_PTCHECK), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_PERSONALTRUST), SW_HIDE); }
//
// Rebase the static line
//
hControl = GetDlgItem(hwnd, IDC_SEPARATORLINE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
//
// Rebase the buttons
//
hControl = GetDlgItem(hwnd, IDYES); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
hControl = GetDlgItem(hwnd, IDNO); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
hControl = GetDlgItem(hwnd, IDMORE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
//
// Resize the bitmap and the dialog rectangle if necessary
//
if ( deltavpos > 0 ) { int cyupd;
hControl = GetDlgItem(hwnd, IDC_VERBMP); GetWindowRect(hControl, &rect);
cyupd = CalculateControlVerticalDistance( hwnd, IDC_VERBMP, IDC_SEPARATORLINE );
cyupd -= bmptosep;
SetWindowPos( hControl, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE );
GetWindowRect(hwnd, &rect);
cyupd = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE );
cyupd = septodlg - cyupd;
SetWindowPos( hwnd, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); }
//
// check for overridden button texts
//
this->SetupButtons(hwnd);
//
// Set focus to appropriate control
//
hControl = GetDlgItem(hwnd, IDNO); ::PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM) hControl, (LPARAM) MAKEWORD(TRUE, 0)); return( FALSE ); }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::OnYes, public
//
// Synopsis: process IDYES button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CVerifiedTrustUI::OnYes (HWND hwnd) { //
// Set the invoke result
//
m_hrInvokeResult = S_OK;
//
// Add the publisher to the trust database
//
if ( SendDlgItemMessage( hwnd, IDC_PTCHECK, BM_GETCHECK, 0, 0 ) == BST_CHECKED ) { m_riih.AddPublisherToPersonalTrust(); }
//
// End the dialog processing
//
EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::OnNo, public
//
// Synopsis: process IDNO button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CVerifiedTrustUI::OnNo (HWND hwnd) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED;
EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CVerifiedTrustUI::OnMore, public
//
// Synopsis: process the IDMORE button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CVerifiedTrustUI::OnMore (HWND hwnd) { WinHelp(hwnd, "SECAUTH.HLP", HELP_CONTEXT, IDH_SECAUTH_SIGNED);
// ACUIViewHTMLHelpTopic(hwnd, "sec_signed.htm");
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::CUnverifiedTrustUI, public
//
// Synopsis: Constructor
//
// Arguments: [riih] -- invoke info helper reference
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CUnverifiedTrustUI::CUnverifiedTrustUI (CInvokeInfoHelper& riih, HRESULT& rhr) : IACUIControl( riih ), m_pszNoAuthenticity( NULL ), m_pszProblemsBelow( NULL ), m_pszInstallAndRun3( NULL ) { DWORD_PTR aMessageArgument[3];
//
// Initialize the publisher link subclass data
//
m_lsdPublisher.uId = IDC_PUBLISHER; m_lsdPublisher.hwndParent = NULL; m_lsdPublisher.wpPrev = (WNDPROC)NULL; m_lsdPublisher.pvData = (LPVOID)&riih; m_lsdPublisher.uToolTipText = IDS_CLICKHEREFORCERT;
m_lsdOpusInfo.uId = IDC_INSTALLANDRUN; m_lsdOpusInfo.hwndParent = NULL; m_lsdOpusInfo.wpPrev = (WNDPROC)NULL; m_lsdOpusInfo.pvData = &riih; m_lsdOpusInfo.uToolTipText = (DWORD_PTR)riih.ControlWebPage(); // IDS_CLICKHEREFOROPUSINFO;
m_lsdAdvanced.uId = IDC_ADVANCED; m_lsdAdvanced.hwndParent = NULL; m_lsdAdvanced.wpPrev = (WNDPROC)NULL; m_lsdAdvanced.pvData = &riih; m_lsdAdvanced.uToolTipText = IDS_CLICKHEREFORADVANCED;
//
// Format the no authenticity string
//
rhr = FormatACUIResourceString( IDS_NOAUTHENTICITY, NULL, &m_pszNoAuthenticity );
//
// Format the problems below string
//
if ( rhr == S_OK ) { aMessageArgument[0] = (DWORD_PTR)m_riih.ErrorStatement();
rhr = FormatACUIResourceString( IDS_PROBLEMSBELOW, aMessageArgument, &m_pszProblemsBelow ); }
//
// Format the install and run string
//
if ( rhr == S_OK ) { if (m_riih.CertTimestamp()) { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionText; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = (DWORD_PTR)m_riih.CertTimestamp(); } else { aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionTextNoTS; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject(); aMessageArgument[2] = NULL; }
rhr = FormatACUIResourceString(0, aMessageArgument, &m_pszInstallAndRun3); } }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::~CUnverifiedTrustUI, public
//
// Synopsis: Destructor
//
// Arguments: (none)
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CUnverifiedTrustUI::~CUnverifiedTrustUI () { DELETE_OBJECT(m_pszNoAuthenticity); DELETE_OBJECT(m_pszProblemsBelow); DELETE_OBJECT(m_pszInstallAndRun3); }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::InvokeUI, public
//
// Synopsis: invoke the UI
//
// Arguments: [hDisplay] -- parent window
//
// Returns: S_OK, user trusts the subject
// TRUST_E_SUBJECT_NOT_TRUSTED, user does NOT trust the subject
// Any other valid HRESULT
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT CUnverifiedTrustUI::InvokeUI (HWND hDisplay) { HRESULT hr = S_OK;
//
// Bring up the dialog
//
if ( DialogBoxParamU( g_hModule, (LPWSTR) MAKEINTRESOURCE(IDD_DIALOG2_UNVERIFIED), hDisplay, ACUIMessageProc, (LPARAM)this ) == -1 ) { return( HRESULT_FROM_WIN32(GetLastError()) ); }
//
// The result has been stored as a member
//
return( m_hrInvokeResult ); }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::OnInitDialog, public
//
// Synopsis: dialog initialization
//
// Arguments: [hwnd] -- dialog window
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if successful init, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CUnverifiedTrustUI::OnInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam) { HWND hControl; int deltavpos = 0; int deltaheight; int bmptosep; int septodlg; RECT rect;
//
// Setup the publisher link subclass data parent window
//
m_lsdPublisher.hwndParent = hwnd; m_lsdOpusInfo.hwndParent = hwnd; m_lsdAdvanced.hwndParent = hwnd;
//
// Render the no authenticity statement
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_NOAUTHENTICITY, IDC_PROBLEMSBELOW, m_pszNoAuthenticity, deltavpos, FALSE, NULL, NULL, 0, NULL );
//
// Render the problems below string
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PROBLEMSBELOW, IDC_INSTALLANDRUN3, m_pszProblemsBelow, deltavpos, FALSE, NULL, NULL, 0, NULL );
//
// Render the install and run string
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_INSTALLANDRUN3, IDC_PUBLISHER2, m_pszInstallAndRun3, deltavpos, (m_riih.ControlWebPage()) ? TRUE : FALSE, (WNDPROC)ACUILinkSubclass, &m_lsdOpusInfo, 0, m_riih.Subject());
//
// Calculate the distances from the bottom of the bitmap to the top
// of the separator and from the bottom of the separator to the bottom
// of the dialog
//
bmptosep = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP2, IDC_SEPARATORLINE );
septodlg = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE );
//
// Render the publisher, give it a "link" look and feel
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_PUBLISHER2, IDC_ADVANCED, m_riih.Publisher(), deltavpos, m_riih.IsKnownPublisher() && m_riih.IsCertViewPropertiesAvailable(), (WNDPROC)ACUILinkSubclass, &m_lsdPublisher, bmptosep, NULL );
if ((m_riih.AdvancedLink()) && (m_riih.ProviderData()->psPfns->psUIpfns->pfnOnAdvancedClick)) { deltavpos = RenderACUIStringToEditControl( hwnd, IDC_ADVANCED, IDC_SEPARATORLINE, m_riih.AdvancedLink(), deltavpos, TRUE, (WNDPROC)ACUILinkSubclass, &m_lsdAdvanced, 0, NULL ); } else { ShowWindow(GetDlgItem(hwnd, IDC_ADVANCED), SW_HIDE); }
//
// Rebase the static line
//
hControl = GetDlgItem(hwnd, IDC_SEPARATORLINE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
//
// Rebase the buttons
//
hControl = GetDlgItem(hwnd, IDYES); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
hControl = GetDlgItem(hwnd, IDNO); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
hControl = GetDlgItem(hwnd, IDMORE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
//
// Resize the bitmap and the dialog rectangle if necessary
//
if ( deltavpos > 0 ) { int cyupd;
hControl = GetDlgItem(hwnd, IDC_NOVERBMP2); GetWindowRect(hControl, &rect);
cyupd = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP2, IDC_SEPARATORLINE );
cyupd -= bmptosep;
SetWindowPos( hControl, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE );
GetWindowRect(hwnd, &rect);
cyupd = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE );
cyupd = septodlg - cyupd;
SetWindowPos( hwnd, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); }
//
// check for overridden button texts
//
this->SetupButtons(hwnd);
//
// Set focus to appropriate control
//
hControl = GetDlgItem(hwnd, IDNO); ::PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM) hControl, (LPARAM) MAKEWORD(TRUE, 0));
return( FALSE ); }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::OnYes, public
//
// Synopsis: process IDYES button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CUnverifiedTrustUI::OnYes (HWND hwnd) { m_hrInvokeResult = S_OK;
EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::OnNo, public
//
// Synopsis: process IDNO button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CUnverifiedTrustUI::OnNo (HWND hwnd) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED;
EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CUnverifiedTrustUI::OnMore, public
//
// Synopsis: process the IDMORE button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CUnverifiedTrustUI::OnMore (HWND hwnd) { WinHelp(hwnd, "SECAUTH.HLP", HELP_CONTEXT, IDH_SECAUTH_SIGNED_N_INVALID);
// ACUIViewHTMLHelpTopic(hwnd, "sec_signed_n_invalid.htm");
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::CNoSignatureUI, public
//
// Synopsis: Constructor
//
// Arguments: [riih] -- invoke info helper
// [rhr] -- result code reference
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CNoSignatureUI::CNoSignatureUI (CInvokeInfoHelper& riih, HRESULT& rhr) : IACUIControl( riih ), m_pszInstallAndRun2( NULL ), m_pszNoPublisherFound( NULL ) { DWORD_PTR aMessageArgument[2];
//
// Format the install and run string
//
aMessageArgument[0] = (DWORD_PTR)m_pszCopyActionTextNotSigned; aMessageArgument[1] = (DWORD_PTR)m_riih.Subject();
rhr = FormatACUIResourceString(0, aMessageArgument, &m_pszInstallAndRun2);
//
// Format the no publisher found string
//
if ( rhr == S_OK ) { aMessageArgument[0] = (DWORD_PTR)m_riih.ErrorStatement();
rhr = FormatACUIResourceString( IDS_NOPUBLISHERFOUND, aMessageArgument, &m_pszNoPublisherFound ); } }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::~CNoSignatureUI, public
//
// Synopsis: Destructor
//
// Arguments: (none)
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CNoSignatureUI::~CNoSignatureUI () { DELETE_OBJECT(m_pszInstallAndRun2); DELETE_OBJECT(m_pszNoPublisherFound); }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::InvokeUI, public
//
// Synopsis: invoke the UI
//
// Arguments: [hDisplay] -- parent window
//
// Returns: S_OK, user trusts the subject
// TRUST_E_SUBJECT_NOT_TRUSTED, user does NOT trust the subject
// Any other valid HRESULT
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT CNoSignatureUI::InvokeUI (HWND hDisplay) { HRESULT hr = S_OK;
//
// Bring up the dialog
//
if ( DialogBoxParamU( g_hModule, (LPWSTR) MAKEINTRESOURCE(IDD_DIALOG3_NOSIGNATURE), hDisplay, ACUIMessageProc, (LPARAM)this ) == -1 ) { return( HRESULT_FROM_WIN32(GetLastError()) ); }
//
// The result has been stored as a member
//
return( m_hrInvokeResult ); }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::OnInitDialog, public
//
// Synopsis: dialog initialization
//
// Arguments: [hwnd] -- dialog window
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if successful init, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CNoSignatureUI::OnInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam) { HWND hControl; int deltavpos = 0; int deltaheight; int bmptosep; int septodlg; RECT rect;
//
// Render the install and run string
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_INSTALLANDRUN2, IDC_NOPUBLISHERFOUND, m_pszInstallAndRun2, deltavpos, FALSE, NULL, NULL, 0, NULL );
//
// Calculate the distances from the bottom of the bitmap to the top
// of the separator and from the bottom of the separator to the bottom
// of the dialog
//
bmptosep = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP, IDC_SEPARATORLINE );
septodlg = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE );
//
// Render the no publisher found statement
//
deltavpos = RenderACUIStringToEditControl( hwnd, IDC_NOPUBLISHERFOUND, IDC_SEPARATORLINE, m_pszNoPublisherFound, deltavpos, FALSE, NULL, NULL, bmptosep, NULL );
//
// Rebase the static line
//
hControl = GetDlgItem(hwnd, IDC_SEPARATORLINE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
//
// Rebase the buttons
//
hControl = GetDlgItem(hwnd, IDYES); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
hControl = GetDlgItem(hwnd, IDNO); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
hControl = GetDlgItem(hwnd, IDMORE); RebaseControlVertical(hwnd, hControl, NULL, FALSE, deltavpos, 0, 0, &deltaheight); assert( deltaheight == 0 );
//
// Resize the bitmap and the dialog rectangle if necessary
//
if ( deltavpos > 0 ) { int cyupd;
hControl = GetDlgItem(hwnd, IDC_NOVERBMP); GetWindowRect(hControl, &rect);
cyupd = CalculateControlVerticalDistance( hwnd, IDC_NOVERBMP, IDC_SEPARATORLINE );
cyupd -= bmptosep;
SetWindowPos( hControl, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE );
GetWindowRect(hwnd, &rect);
cyupd = CalculateControlVerticalDistanceFromDlgBottom( hwnd, IDC_SEPARATORLINE );
cyupd = septodlg - cyupd;
SetWindowPos( hwnd, NULL, 0, 0, rect.right - rect.left, (rect.bottom - rect.top) + cyupd, SWP_NOZORDER | SWP_NOMOVE ); }
//
// check for overridden button texts
//
this->SetupButtons(hwnd);
//
// Set focus to appropriate control
//
hControl = GetDlgItem(hwnd, IDNO); ::PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM) hControl, (LPARAM) MAKEWORD(TRUE, 0));
return( FALSE ); }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::OnYes, public
//
// Synopsis: process IDYES button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CNoSignatureUI::OnYes (HWND hwnd) { m_hrInvokeResult = S_OK;
EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::OnNo, public
//
// Synopsis: process IDNO button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CNoSignatureUI::OnNo (HWND hwnd) { m_hrInvokeResult = TRUST_E_SUBJECT_NOT_TRUSTED;
EndDialog(hwnd, (int)m_hrInvokeResult); return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Member: CNoSignatureUI::OnMore, public
//
// Synopsis: process the IDMORE button click
//
// Arguments: [hwnd] -- window handle
//
// Returns: TRUE
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL CNoSignatureUI::OnMore (HWND hwnd) { WinHelp(hwnd, "SECAUTH.HLP", HELP_CONTEXT, IDH_SECAUTH_UNSIGNED);
// ACUIViewHTMLHelpTopic(hwnd, "sec_unsigned.htm");
return( TRUE ); }
//+---------------------------------------------------------------------------
//
// Function: ACUIMessageProc
//
// Synopsis: message proc to process UI messages
//
// Arguments: [hwnd] -- window
// [uMsg] -- message id
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if message processing should continue, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
INT_PTR CALLBACK ACUIMessageProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { IACUIControl* pUI = NULL;
//
// Get the control
//
if (uMsg == WM_INITDIALOG) { pUI = (IACUIControl *)lParam; SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam); } else { pUI = (IACUIControl *)GetWindowLongPtr(hwnd, DWLP_USER); }
//
// If we couldn't find it, we must not have set it yet, so ignore this
// message
//
if ( pUI == NULL ) { return( FALSE ); }
//
// Pass the message on to the control
//
return( pUI->OnUIMessage(hwnd, uMsg, wParam, lParam) ); }
int GetRichEditControlLineHeight(HWND hwnd) { RECT rect; POINT pointInFirstRow; POINT pointInSecondRow; int secondLineCharIndex; int i; RECT originalRect;
GetWindowRect(hwnd, &originalRect);
//
// HACK ALERT, believe it or not there is no way to get the height of the current
// font in the edit control, so get the position a character in the first row and the position
// of a character in the second row, and do the subtraction to get the
// height of the font
//
SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInFirstRow, (LPARAM) 0);
//
// HACK ON TOP OF HACK ALERT,
// since there may not be a second row in the edit box, keep reducing the width
// by half until the first row falls over into the second row, then get the position
// of the first char in the second row and finally reset the edit box size back to
// it's original size
//
secondLineCharIndex = (int)SendMessageA(hwnd, EM_LINEINDEX, (WPARAM) 1, (LPARAM) 0); if (secondLineCharIndex == -1) { for (i=0; i<20; i++) { GetWindowRect(hwnd, &rect); SetWindowPos( hwnd, NULL, 0, 0, (rect.right-rect.left)/2, rect.bottom-rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); secondLineCharIndex = (int)SendMessageA(hwnd, EM_LINEINDEX, (WPARAM) 1, (LPARAM) 0); if (secondLineCharIndex != -1) { break; } }
if (secondLineCharIndex == -1) { // if we failed after twenty tries just reset the control to its original size
// and get the heck outa here!!
SetWindowPos(hwnd, NULL, 0, 0, originalRect.right-originalRect.left, originalRect.bottom-originalRect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
return 0; }
SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInSecondRow, (LPARAM) secondLineCharIndex);
SetWindowPos(hwnd, NULL, 0, 0, originalRect.right-originalRect.left, originalRect.bottom-originalRect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); } else { SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInSecondRow, (LPARAM) secondLineCharIndex); } return (pointInSecondRow.y - pointInFirstRow.y); }
//+---------------------------------------------------------------------------
//
// Function: RebaseControlVertical
//
// Synopsis: Take the window control, if it has to be resized for text, do
// so. Reposition it adjusted for delta pos and return any
// height difference for the text resizing
//
// Arguments: [hwndDlg] -- host dialog
// [hwnd] -- control
// [hwndNext] -- next control
// [fResizeForText] -- resize for text flag
// [deltavpos] -- delta vertical position
// [oline] -- original number of lines
// [minsep] -- minimum separator
// [pdeltaheight] -- delta in control height
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
VOID RebaseControlVertical ( HWND hwndDlg, HWND hwnd, HWND hwndNext, BOOL fResizeForText, int deltavpos, int oline, int minsep, int* pdeltaheight ) { int x = 0; int y = 0; int odn = 0; int orig_w; RECT rect; RECT rectNext; RECT rectDlg; TEXTMETRIC tm;
//
// Set the delta height to zero for now. If we resize the text
// a new one will be calculated
//
*pdeltaheight = 0;
//
// Get the control window rectangle
//
GetWindowRect(hwnd, &rect); GetWindowRect(hwndNext, &rectNext);
odn = rectNext.top - rect.bottom;
orig_w = rect.right - rect.left;
MapWindowPoints(NULL, hwndDlg, (LPPOINT) &rect, 2);
//
// If we have to resize the control due to text, find out what font
// is being used and the number of lines of text. From that we'll
// calculate what the new height for the control is and set it up
//
if ( fResizeForText == TRUE ) { HDC hdc; HFONT hfont; HFONT hfontOld; int cline; int h; int w; int dh; int lineHeight; //
// Get the metrics of the current control font
//
hdc = GetDC(hwnd); if (hdc == NULL) { hdc = GetDC(NULL); if (hdc == NULL) { return; } }
hfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0); if ( hfont == NULL ) { hfont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0); }
hfontOld = (HFONT)SelectObject(hdc, hfont); GetTextMetrics(hdc, &tm);
lineHeight = GetRichEditControlLineHeight(hwnd); if (lineHeight == 0) { lineHeight = tm.tmHeight; } //
// Set the minimum separation value
//
if ( minsep == 0 ) { minsep = lineHeight; }
//
// Calculate the width and the new height needed
//
cline = (int)SendMessage(hwnd, EM_GETLINECOUNT, 0, 0);
h = cline * lineHeight;
w = GetEditControlMaxLineWidth(hwnd, hdc, cline); w += 3; // a little bump to make sure string will fit
if (w > orig_w) { w = orig_w; }
SelectObject(hdc, hfontOld); ReleaseDC(hwnd, hdc);
//
// Calculate an addition to height by checking how much space was
// left when there were the original # of lines and making sure that
// that amount is still left when we do any adjustments
//
h += ( ( rect.bottom - rect.top ) - ( oline * lineHeight ) ); dh = h - ( rect.bottom - rect.top );
//
// If the current height is too small, adjust for it, otherwise
// leave the current height and just adjust for the width
//
if ( dh > 0 ) { SetWindowPos(hwnd, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); } else { SetWindowPos( hwnd, NULL, 0, 0, w, ( rect.bottom - rect.top ), SWP_NOZORDER | SWP_NOMOVE ); }
if ( cline < SendMessage(hwnd, EM_GETLINECOUNT, 0, 0) ) { AdjustEditControlWidthToLineCount(hwnd, cline, &tm); } }
//
// If we have to use deltavpos then calculate the X and the new Y
// and set the window position appropriately
//
if ( deltavpos != 0 ) { GetWindowRect(hwndDlg, &rectDlg);
MapWindowPoints(NULL, hwndDlg, (LPPOINT) &rectDlg, 2);
x = rect.left - rectDlg.left - GetSystemMetrics(SM_CXEDGE); y = rect.top - rectDlg.top - GetSystemMetrics(SM_CYCAPTION) + deltavpos;
SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); }
//
// Get the window rect for the next control and see what the distance
// is between the current control and it. With that we must now
// adjust our deltaheight, if the distance to the next control is less
// than a line height then make it a line height, otherwise just let it
// be
//
if ( hwndNext != NULL ) { int dn;
GetWindowRect(hwnd, &rect); GetWindowRect(hwndNext, &rectNext);
dn = rectNext.top - rect.bottom;
if ( odn > minsep ) { if ( dn < minsep ) { *pdeltaheight = minsep - dn; } } else { if ( dn < odn ) { *pdeltaheight = odn - dn; } } } }
//+---------------------------------------------------------------------------
//
// Function: ACUISetArrowCursorSubclass
//
// Synopsis: subclass routine for setting the arrow cursor. This can be
// set on multiline edit routines used in the dialog UIs for
// the default Authenticode provider
//
// Arguments: [hwnd] -- window handle
// [uMsg] -- message id
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if message handled, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
LRESULT CALLBACK ACUISetArrowCursorSubclass ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { HDC hdc; WNDPROC wndproc; PAINTSTRUCT ps;
wndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch ( uMsg ) { case WM_SETCURSOR:
SetCursor(LoadCursor(NULL, IDC_ARROW)); return( TRUE );
break;
case WM_CHAR:
if ( wParam != (WPARAM)' ' ) { break; }
case WM_LBUTTONDOWN:
if ( hwnd == GetDlgItem(GetParent(hwnd), IDC_PERSONALTRUST) ) { int check; HWND hwndCheck;
//
// Toggle the check state of the PTCHECK control if the
// personal trust statement is clicked on
//
hwndCheck = GetDlgItem(GetParent(hwnd), IDC_PTCHECK); check = (int)SendMessage(hwndCheck, BM_GETCHECK, 0, 0);
if ( check == BST_CHECKED ) { check = BST_UNCHECKED; } else if ( check == BST_UNCHECKED ) { check = BST_CHECKED; } else { check = BST_UNCHECKED; }
SendMessage(hwndCheck, BM_SETCHECK, (WPARAM)check, 0); SetFocus(hwnd); return( TRUE ); }
return(TRUE);
case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN:
return( TRUE );
break;
case EM_SETSEL:
return( TRUE );
break;
case WM_PAINT:
CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam); if ( hwnd == GetFocus() ) { DrawFocusRectangle(hwnd, NULL); } return( TRUE );
break;
case WM_SETFOCUS:
if ( hwnd != GetDlgItem(GetParent(hwnd), IDC_PERSONALTRUST) ) { SetFocus(GetNextDlgTabItem(GetParent(hwnd), hwnd, FALSE)); return( TRUE ); } else { InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); SetCursor(LoadCursor(NULL, IDC_ARROW)); return( TRUE ); }
break;
case WM_KILLFOCUS:
InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return( TRUE );
}
return(CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam)); }
//+---------------------------------------------------------------------------
//
// Function: SubclassEditControlForArrowCursor
//
// Synopsis: subclasses edit control so that the arrow cursor can replace
// the edit bar
//
// Arguments: [hwndEdit] -- edit control
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
VOID SubclassEditControlForArrowCursor (HWND hwndEdit) { LONG_PTR PrevWndProc;
PrevWndProc = GetWindowLongPtr(hwndEdit, GWLP_WNDPROC); SetWindowLongPtr(hwndEdit, GWLP_USERDATA, (LONG_PTR)PrevWndProc); SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)ACUISetArrowCursorSubclass); }
//+---------------------------------------------------------------------------
//
// Function: SubclassEditControlForLink
//
// Synopsis: subclasses the edit control for a link using the link subclass
// data
//
// Arguments: [hwndDlg] -- dialog
// [hwndEdit] -- edit control
// [wndproc] -- window proc to subclass with
// [plsd] -- data to pass on to window proc
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
VOID SubclassEditControlForLink ( HWND hwndDlg, HWND hwndEdit, WNDPROC wndproc, PTUI_LINK_SUBCLASS_DATA plsd ) { HWND hwndTip;
plsd->hwndTip = CreateWindowA( TOOLTIPS_CLASSA, (LPSTR)NULL, WS_POPUP | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, (HMENU)NULL, g_hModule, NULL );
if ( plsd->hwndTip != NULL ) { TOOLINFOA tia; DWORD cb; LPSTR psz;
memset(&tia, 0, sizeof(TOOLINFOA)); tia.cbSize = sizeof(TOOLINFOA); tia.hwnd = hwndEdit; tia.uId = 1; tia.hinst = g_hModule; //GetClientRect(hwndEdit, &tia.rect);
SendMessage(hwndEdit, EM_GETRECT, 0, (LPARAM)&tia.rect);
//
// if plsd->uToolTipText is a string then convert it
//
if (plsd->uToolTipText &0xffff0000) { cb = WideCharToMultiByte( 0, 0, (LPWSTR)plsd->uToolTipText, -1, NULL, 0, NULL, NULL);
if (NULL == (psz = new char[cb])) { return; }
WideCharToMultiByte( 0, 0, (LPWSTR)plsd->uToolTipText, -1, psz, cb, NULL, NULL); tia.lpszText = psz; } else { tia.lpszText = (LPSTR)plsd->uToolTipText; }
SendMessage(plsd->hwndTip, TTM_ADDTOOL, 0, (LPARAM)&tia);
if (plsd->uToolTipText &0xffff0000) { delete[] psz; } }
plsd->fMouseCaptured = FALSE; plsd->wpPrev = (WNDPROC)GetWindowLongPtr(hwndEdit, GWLP_WNDPROC); SetWindowLongPtr(hwndEdit, GWLP_USERDATA, (LONG_PTR)plsd); SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)wndproc); }
//+---------------------------------------------------------------------------
//
// Function: ACUILinkSubclass
//
// Synopsis: subclass for the publisher link
//
// Arguments: [hwnd] -- window handle
// [uMsg] -- message id
// [wParam] -- parameter 1
// [lParam] -- parameter 2
//
// Returns: TRUE if message handled, FALSE otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
LRESULT CALLBACK ACUILinkSubclass ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { PTUI_LINK_SUBCLASS_DATA plsd; CInvokeInfoHelper* piih;
plsd = (PTUI_LINK_SUBCLASS_DATA)GetWindowLongPtr(hwnd, GWLP_USERDATA); piih = (CInvokeInfoHelper *)plsd->pvData;
switch ( uMsg ) { case WM_SETCURSOR:
if (!plsd->fMouseCaptured) { SetCapture(hwnd); plsd->fMouseCaptured = TRUE; }
SetCursor(LoadCursor((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDC_TUIHAND))); return( TRUE );
break;
case WM_CHAR:
if ( wParam != (WPARAM)' ') { break; }
// fall through to wm_lbuttondown....
case WM_LBUTTONDOWN:
SetFocus(hwnd);
switch(plsd->uId) { case IDC_PUBLISHER: piih->CallCertViewProperties(plsd->hwndParent); break;
case IDC_INSTALLANDRUN: piih->CallWebLink(plsd->hwndParent, (WCHAR *)piih->ControlWebPage()); break;
case IDC_AUTHENTICITY: piih->CallWebLink(plsd->hwndParent, (WCHAR *)piih->CAWebPage()); break;
case IDC_ADVANCED: piih->CallAdvancedLink(plsd->hwndParent); break; }
return( TRUE );
case WM_LBUTTONDBLCLK: case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN:
return( TRUE );
case EM_SETSEL:
return( TRUE );
case WM_PAINT:
CallWindowProc(plsd->wpPrev, hwnd, uMsg, wParam, lParam); if ( hwnd == GetFocus() ) { DrawFocusRectangle(hwnd, NULL); } return( TRUE );
case WM_SETFOCUS:
if ( hwnd == GetFocus() ) { InvalidateRect(hwnd, NULL, FALSE); UpdateWindow(hwnd); SetCursor(LoadCursor((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDC_TUIHAND))); return( TRUE ); } break;
case WM_KILLFOCUS:
InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); SetCursor(LoadCursor(NULL, IDC_ARROW));
return( TRUE );
case WM_MOUSEMOVE:
MSG msg; DWORD dwCharLine; CHARFORMAT sCharFmt; RECT rect; int xPos, yPos;
memset(&msg, 0, sizeof(MSG)); msg.hwnd = hwnd; msg.message = uMsg; msg.wParam = wParam; msg.lParam = lParam;
SendMessage(plsd->hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
// check to see if the mouse is in this windows rect, if not, then reset
// the cursor to an arrow and release the mouse
GetClientRect(hwnd, &rect); xPos = LOWORD(lParam); yPos = HIWORD(lParam); if ((xPos < 0) || (yPos < 0) || (xPos > (rect.right - rect.left)) || (yPos > (rect.bottom - rect.top))) { SetCursor(LoadCursor(NULL, IDC_ARROW)); ReleaseCapture(); plsd->fMouseCaptured = FALSE; }
/*
warning! EM_CHARFROMPOS gets an access violation!
dwCharLine = SendMessage(hwnd, EM_CHARFROMPOS, 0, lParam);
if (dwCharLine == (-1)) { return(TRUE); }
SendMessage(hwnd, EM_SETSEL, (WPARAM)LOWORD(dwCharLine), (LPARAM)(LOWORD(dwCharLine) + 1));
memset(&sCharFmt, 0x00, sizeof(CHARFORMAT)); sCharFmt.cbSize = sizeof(CHARFORMAT);
SendMessage(hwnd, EM_GETCHARFORMAT, TRUE, (LPARAM)&sCharFmt);
if (sCharFmt.dwEffects & CFE_UNDERLINE) { SetCursor(LoadCursor((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), MAKEINTRESOURCE(IDC_TUIHAND))); } else { SetCursor(LoadCursor(NULL, IDC_ARROW)); }
*/ return( TRUE ); }
return(CallWindowProc(plsd->wpPrev, hwnd, uMsg, wParam, lParam)); }
//+---------------------------------------------------------------------------
//
// Function: FormatACUIResourceString
//
// Synopsis: formats a string given a resource id and message arguments
//
// Arguments: [StringResourceId] -- resource id
// [aMessageArgument] -- message arguments
// [ppszFormatted] -- formatted string goes here
//
// Returns: S_OK if successful, any valid HRESULT otherwise
//
//----------------------------------------------------------------------------
HRESULT FormatACUIResourceString ( UINT StringResourceId, DWORD_PTR* aMessageArgument, LPWSTR* ppszFormatted ) { HRESULT hr = S_OK; WCHAR sz[MAX_LOADSTRING_BUFFER]; LPVOID pvMsg;
pvMsg = NULL; sz[0] = NULL;
//
// Load the string resource and format the message with that string and
// the message arguments
//
if (StringResourceId != 0) { if ( LoadStringU(g_hModule, StringResourceId, sz, MAX_LOADSTRING_BUFFER) == 0 ) { return(HRESULT_FROM_WIN32(GetLastError())); }
if ( FormatMessageU(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, sz, 0, 0, (LPWSTR)&pvMsg, 0, (va_list *)aMessageArgument) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); } } else { if ( FormatMessageU(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (char *)aMessageArgument[0], 0, 0, (LPWSTR)&pvMsg, 0, (va_list *)&aMessageArgument[1]) == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); } }
if (pvMsg) { *ppszFormatted = new WCHAR[wcslen((WCHAR *)pvMsg) + 1];
if (*ppszFormatted) { wcscpy(*ppszFormatted, (WCHAR *)pvMsg); }
LocalFree(pvMsg); }
return( hr ); }
//+---------------------------------------------------------------------------
//
// Function: RenderACUIStringToEditControl
//
// Synopsis: renders a string to the control given and if requested, gives
// it a link look and feel, subclassed to the wndproc and plsd
// given
//
// Arguments: [hwndDlg] -- dialog window handle
// [ControlId] -- control id
// [NextControlId] -- next control id
// [psz] -- string
// [deltavpos] -- delta vertical position
// [fLink] -- a link?
// [wndproc] -- optional wndproc, valid if fLink == TRUE
// [plsd] -- optional plsd, valid if fLink === TRUE
// [minsep] -- minimum separation
// [pszThisTextOnlyInLink -- only change this text.
//
// Returns: delta in height of the control
//
// Notes:
//
//----------------------------------------------------------------------------
int RenderACUIStringToEditControl ( HWND hwndDlg, UINT ControlId, UINT NextControlId, LPCWSTR psz, int deltavpos, BOOL fLink, WNDPROC wndproc, PTUI_LINK_SUBCLASS_DATA plsd, int minsep, LPCWSTR pszThisTextOnlyInLink ) { HWND hControl; int deltaheight = 0; int oline = 0; int hkcharpos;
//
// Get the control and set the text on it, make sure the background
// is right if it is a rich edit control
//
hControl = GetDlgItem(hwndDlg, ControlId); oline = (int)SendMessage(hControl, EM_GETLINECOUNT, 0, 0); CryptUISetRicheditTextW(hwndDlg, ControlId, L""); CryptUISetRicheditTextW(hwndDlg, ControlId, psz); //SetWindowTextU(hControl, psz);
//
// If there is a '&' in the string, then get rid of it
//
hkcharpos = GetHotKeyCharPosition(hControl); if (IDC_PERSONALTRUST == ControlId && hkcharpos != 0) { CHARRANGE cr; CHARFORMAT cf;
cr.cpMin = hkcharpos - 1; cr.cpMax = hkcharpos;
SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM) &cr); SendMessage(hControl, EM_REPLACESEL, FALSE, (LPARAM) "");
cr.cpMin = -1; cr.cpMax = 0; SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM) &cr); }
SendMessage( hControl, EM_SETBKGNDCOLOR, 0, (LPARAM)GetSysColor(COLOR_3DFACE) );
//
// If we have a link then update for the link look
//
if ( fLink == TRUE ) { CHARFORMAT cf;
memset(&cf, 0, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_COLOR | CFM_UNDERLINE;
cf.crTextColor = RGB(0, 0, 255); cf.dwEffects |= CFM_UNDERLINE;
if (pszThisTextOnlyInLink) { FINDTEXTEX ft; DWORD pos; char *pszOnlyThis; DWORD cb;
cb = WideCharToMultiByte( 0, 0, pszThisTextOnlyInLink, -1, NULL, 0, NULL, NULL);
if (NULL == (pszOnlyThis = new char[cb])) { return 0; }
WideCharToMultiByte( 0, 0, pszThisTextOnlyInLink, -1, pszOnlyThis, cb, NULL, NULL);
memset(&ft, 0x00, sizeof(FINDTEXTEX)); ft.chrg.cpMin = 0; ft.chrg.cpMax = (-1); ft.lpstrText = (char *)pszOnlyThis;
if ((pos = (DWORD)SendMessage(hControl, EM_FINDTEXTEX, 0, (LPARAM)&ft)) != (-1)) { SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM)&ft.chrgText); SendMessage(hControl, EM_SETCHARFORMAT, SCF_WORD | SCF_SELECTION, (LPARAM)&cf); ft.chrgText.cpMin = 0; ft.chrgText.cpMax = 0; SendMessage(hControl, EM_EXSETSEL, 0, (LPARAM)&ft.chrgText); }
delete[] pszOnlyThis; } else { SendMessage(hControl, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); } }
//
// Rebase the control
//
RebaseControlVertical( hwndDlg, hControl, GetDlgItem(hwndDlg, NextControlId), TRUE, deltavpos, oline, minsep, &deltaheight );
//
// If we have the link look then we must subclass for the appropriate
// link feel, otherwise we subclass for a static text control feel
//
if ( fLink == TRUE ) { SubclassEditControlForLink(hwndDlg, hControl, wndproc, plsd); } else { SubclassEditControlForArrowCursor(hControl); }
return( deltaheight ); }
//+---------------------------------------------------------------------------
//
// Function: CalculateControlVerticalDistance
//
// Synopsis: calculates the vertical distance from the bottom of Control1
// to the top of Control2
//
// Arguments: [hwnd] -- parent dialog
// [Control1] -- first control
// [Control2] -- second control
//
// Returns: the distance in pixels
//
// Notes: assumes control1 is above control2
//
//----------------------------------------------------------------------------
int CalculateControlVerticalDistance (HWND hwnd, UINT Control1, UINT Control2) { RECT rect1; RECT rect2;
GetWindowRect(GetDlgItem(hwnd, Control1), &rect1); GetWindowRect(GetDlgItem(hwnd, Control2), &rect2);
return( rect2.top - rect1.bottom ); }
//+---------------------------------------------------------------------------
//
// Function: CalculateControlVerticalDistanceFromDlgBottom
//
// Synopsis: calculates the distance from the bottom of the control to
// the bottom of the dialog
//
// Arguments: [hwnd] -- dialog
// [Control] -- control
//
// Returns: the distance in pixels
//
// Notes:
//
//----------------------------------------------------------------------------
int CalculateControlVerticalDistanceFromDlgBottom (HWND hwnd, UINT Control) { RECT rect; RECT rectControl;
GetClientRect(hwnd, &rect); GetWindowRect(GetDlgItem(hwnd, Control), &rectControl);
return( rect.bottom - rectControl.bottom ); }
//+---------------------------------------------------------------------------
//
// Function: ACUICenterWindow
//
// Synopsis: centers the given window
//
// Arguments: [hWndToCenter] -- window handle
//
// Returns: (none)
//
// Notes: This code was stolen from ATL and hacked upon madly :-)
//
//----------------------------------------------------------------------------
VOID ACUICenterWindow (HWND hWndToCenter) { HWND hWndCenter;
// determine owner window to center against
DWORD dwStyle = (DWORD)GetWindowLong(hWndToCenter, GWL_STYLE);
if(dwStyle & WS_CHILD) hWndCenter = ::GetParent(hWndToCenter); else hWndCenter = ::GetWindow(hWndToCenter, GW_OWNER);
if (hWndCenter == NULL) { return; }
// get coordinates of the window relative to its parent
RECT rcDlg; ::GetWindowRect(hWndToCenter, &rcDlg); RECT rcArea; RECT rcCenter; HWND hWndParent; if(!(dwStyle & WS_CHILD)) { // don't center against invisible or minimized windows
if(hWndCenter != NULL) { DWORD dwStyle2 = ::GetWindowLong(hWndCenter, GWL_STYLE); if(!(dwStyle2 & WS_VISIBLE) || (dwStyle2 & WS_MINIMIZE)) hWndCenter = NULL; }
// center within screen coordinates
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
if(hWndCenter == NULL) rcCenter = rcArea; else ::GetWindowRect(hWndCenter, &rcCenter); } else { // center within parent client coordinates
hWndParent = ::GetParent(hWndToCenter);
::GetClientRect(hWndParent, &rcArea); ::GetClientRect(hWndCenter, &rcCenter); ::MapWindowPoints(hWndCenter, hWndParent, (POINT*)&rcCenter, 2); }
int DlgWidth = rcDlg.right - rcDlg.left; int DlgHeight = rcDlg.bottom - rcDlg.top;
// find dialog's upper left based on rcCenter
int xLeft = (rcCenter.left + rcCenter.right) / 2 - DlgWidth / 2; int yTop = (rcCenter.top + rcCenter.bottom) / 2 - DlgHeight / 2;
// if the dialog is outside the screen, move it inside
if(xLeft < rcArea.left) xLeft = rcArea.left; else if(xLeft + DlgWidth > rcArea.right) xLeft = rcArea.right - DlgWidth;
if(yTop < rcArea.top) yTop = rcArea.top; else if(yTop + DlgHeight > rcArea.bottom) yTop = rcArea.bottom - DlgHeight;
// map screen coordinates to child coordinates
::SetWindowPos( hWndToCenter, HWND_TOPMOST, xLeft, yTop, -1, -1, SWP_NOSIZE | SWP_NOACTIVATE ); }
//+---------------------------------------------------------------------------
//
// Function: ACUIViewHTMLHelpTopic
//
// Synopsis: html help viewer
//
// Arguments: [hwnd] -- caller window
// [pszTopic] -- topic
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
VOID ACUIViewHTMLHelpTopic (HWND hwnd, LPSTR pszTopic) { // HtmlHelpA(
// hwnd,
// "%SYSTEMROOT%\\help\\iexplore.chm>large_context",
// HH_DISPLAY_TOPIC,
// (DWORD)pszTopic
// );
}
//+---------------------------------------------------------------------------
//
// Function: GetEditControlMaxLineWidth
//
// Synopsis: gets the maximum line width of the edit control
//
//----------------------------------------------------------------------------
int GetEditControlMaxLineWidth (HWND hwndEdit, HDC hdc, int cline) { int index; int line; int charwidth; int maxwidth = 0; CHAR szMaxBuffer[1024]; WCHAR wsz[1024]; TEXTRANGEA tr; SIZE size;
tr.lpstrText = szMaxBuffer;
for ( line = 0; line < cline; line++ ) { index = (int)SendMessage(hwndEdit, EM_LINEINDEX, (WPARAM)line, 0); charwidth = (int)SendMessage(hwndEdit, EM_LINELENGTH, (WPARAM)index, 0);
tr.chrg.cpMin = index; tr.chrg.cpMax = index + charwidth; SendMessage(hwndEdit, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
wsz[0] = NULL;
MultiByteToWideChar(0, 0, (const char *)tr.lpstrText, -1, &wsz[0], 1024);
if (wsz[0]) { GetTextExtentPoint32W(hdc, &wsz[0], charwidth, &size);
if ( size.cx > maxwidth ) { maxwidth = size.cx; } } }
return( maxwidth ); }
//+---------------------------------------------------------------------------
//
// Function: DrawFocusRectangle
//
// Synopsis: draws the focus rectangle for the edit control
//
//----------------------------------------------------------------------------
void DrawFocusRectangle (HWND hwnd, HDC hdc) { RECT rect; PAINTSTRUCT ps; BOOL fReleaseDC = FALSE;
if ( hdc == NULL ) { hdc = GetDC(hwnd); if ( hdc == NULL ) { return; } fReleaseDC = TRUE; }
GetClientRect(hwnd, &rect); DrawFocusRect(hdc, &rect);
if ( fReleaseDC == TRUE ) { ReleaseDC(hwnd, hdc); } }
//+---------------------------------------------------------------------------
//
// Function: GetHotKeyCharPositionFromString
//
// Synopsis: gets the character position for the hotkey, zero means
// no-hotkey
//
//----------------------------------------------------------------------------
int GetHotKeyCharPositionFromString (LPWSTR pwszText) { LPWSTR psz = pwszText;
while ( ( psz = wcschr(psz, L'&') ) != NULL ) { psz++; if ( *psz != L'&' ) { break; } }
if ( psz == NULL ) { return( 0 ); }
return (int)(( psz - pwszText ) ); }
//+---------------------------------------------------------------------------
//
// Function: GetHotKeyCharPosition
//
// Synopsis: gets the character position for the hotkey, zero means
// no-hotkey
//
//----------------------------------------------------------------------------
int GetHotKeyCharPosition (HWND hwnd) { int nPos = 0; WCHAR szText[MAX_LOADSTRING_BUFFER] = L"";
if (GetWindowTextU(hwnd, szText, MAX_LOADSTRING_BUFFER)) { nPos = GetHotKeyCharPositionFromString(szText); }
return nPos; }
//+---------------------------------------------------------------------------
//
// Function: FormatHotKeyOnEditControl
//
// Synopsis: formats the hot key on an edit control by making it underlined
//
//----------------------------------------------------------------------------
VOID FormatHotKeyOnEditControl (HWND hwnd, int hkcharpos) { CHARRANGE cr; CHARFORMAT cf;
assert( hkcharpos != 0 );
cr.cpMin = hkcharpos - 1; cr.cpMax = hkcharpos;
SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
memset(&cf, 0, sizeof(CHARFORMAT)); cf.cbSize = sizeof(CHARFORMAT); cf.dwMask = CFM_UNDERLINE; cf.dwEffects |= CFM_UNDERLINE;
SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
cr.cpMin = -1; cr.cpMax = 0; SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr); }
//+---------------------------------------------------------------------------
//
// Function: AdjustEditControlWidthToLineCount
//
// Synopsis: adjust edit control width to the given line count
//
//----------------------------------------------------------------------------
void AdjustEditControlWidthToLineCount(HWND hwnd, int cline, TEXTMETRIC* ptm) { RECT rect; int w; int h;
GetWindowRect(hwnd, &rect); h = rect.bottom - rect.top; w = rect.right - rect.left;
while ( cline < SendMessage(hwnd, EM_GETLINECOUNT, 0, 0) ) { w += ptm->tmMaxCharWidth; SetWindowPos(hwnd, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); printf( "Line count adjusted to = %d\n", (DWORD) SendMessage(hwnd, EM_GETLINECOUNT, 0, 0) ); } }
|