windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/trustui/acuictl.cpp

3061 lines
82 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+---------------------------------------------------------------------------
//
// 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)
{
GetWindowTextU(hwnd, pszCombine, wtlen + 1);
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)
);
}
}