You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
808 lines
20 KiB
808 lines
20 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1998 - 1999
|
|
//
|
|
// File: ScInsDlg.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// ScInsDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include <atlconv.h>
|
|
#include "resource.h"
|
|
#include "scdlg.h"
|
|
#include "ScSearch.h"
|
|
#include "ScInsDlg.h"
|
|
#include "statmon.h"
|
|
#include "scHlpArr.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScInsertDlg dialog
|
|
|
|
|
|
CScInsertDlg::CScInsertDlg(CWnd* pParent/*=NULL*/)
|
|
: CDialog(CScInsertDlg::IDD, pParent)
|
|
{
|
|
|
|
// Member Initialization
|
|
m_lLastError = SCARD_S_SUCCESS;
|
|
m_ParentHwnd = pParent;
|
|
m_pOCNW = NULL;
|
|
m_pOCNA = NULL;
|
|
m_pSelectedReader = NULL;
|
|
m_pSubDlg = NULL;
|
|
|
|
m_strTitle.Empty();
|
|
m_strPrompt.Empty();
|
|
m_mstrAllCards = "";
|
|
|
|
//{{AFX_DATA_INIT(CScInsertDlg)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
|
|
CScInsertDlg::~CScInsertDlg()
|
|
{
|
|
// Stop status monitor
|
|
m_monitor.Stop();
|
|
|
|
// Clean up status list!
|
|
if (0 != m_aReaderState.GetSize())
|
|
{
|
|
for (int i = (int)m_aReaderState.GetUpperBound(); i>=0; i--)
|
|
{
|
|
delete m_aReaderState[i];
|
|
}
|
|
|
|
m_aReaderState.RemoveAll();
|
|
}
|
|
}
|
|
|
|
|
|
void CScInsertDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CScInsertDlg)
|
|
DDX_Control(pDX, IDC_DETAILS, m_btnDetails);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CScInsertDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CScInsertDlg)
|
|
ON_MESSAGE( WM_READERSTATUSCHANGE, OnReaderStatusChange )
|
|
ON_BN_CLICKED(IDC_DETAILS, OnDetails)
|
|
ON_WM_HELPINFO()
|
|
ON_WM_CONTEXTMENU()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScInsertDlg data methods
|
|
|
|
/*++
|
|
|
|
LONG Initialize:
|
|
|
|
Stores the open card name pointer in the proper internal struct.
|
|
Determines whether to show the dialog in details or brief mode.
|
|
|
|
Arguments:
|
|
|
|
pOCN(x) - pointer to an open card name ex struct
|
|
|
|
Return Value:
|
|
|
|
A LONG value indicating the status of the requested action. Please
|
|
see the Smartcard header files for additional information.
|
|
|
|
Author:
|
|
|
|
Amanda Matlosz 07/09/1998
|
|
|
|
--*/
|
|
|
|
// ANSI
|
|
LONG CScInsertDlg::Initialize(LPOPENCARDNAMEA_EX pOCNA, DWORD dwNumOKCards, LPCSTR mszOKCards)
|
|
{
|
|
_ASSERTE(NULL != pOCNA);
|
|
if (NULL == pOCNA)
|
|
{
|
|
return SCARD_F_UNKNOWN_ERROR;
|
|
}
|
|
|
|
m_pOCNA = pOCNA;
|
|
|
|
m_strTitle = m_pOCNA->lpstrTitle;
|
|
m_strPrompt = m_pOCNA->lpstrSearchDesc;
|
|
m_mstrAllCards = mszOKCards;
|
|
m_hIcon = pOCNA->hIcon;
|
|
|
|
// hide details if no suitable cards available, else show details
|
|
m_fDetailsShown = (0==dwNumOKCards) ? FALSE : TRUE;
|
|
|
|
// prepare critical section for UI routines
|
|
m_pCritSec = new CCriticalSection();
|
|
if (NULL == m_pCritSec)
|
|
{
|
|
return ERROR_OUTOFMEMORY; // TODO: is another errorcode more appropriate?
|
|
}
|
|
|
|
// put dialog on top
|
|
SetForegroundWindow();
|
|
|
|
return SCARD_S_SUCCESS;
|
|
}
|
|
|
|
//UNICODE
|
|
HRESULT CScInsertDlg::Initialize(LPOPENCARDNAMEW_EX pOCNW, DWORD dwNumOKCards, LPCWSTR mszOKCards)
|
|
{
|
|
_ASSERTE(NULL != pOCNW);
|
|
if (NULL == pOCNW)
|
|
{
|
|
return SCARD_F_UNKNOWN_ERROR;
|
|
}
|
|
|
|
m_pOCNW = pOCNW;
|
|
|
|
m_strTitle = m_pOCNW->lpstrTitle;
|
|
m_strPrompt = m_pOCNW->lpstrSearchDesc;
|
|
m_mstrAllCards = mszOKCards;
|
|
m_hIcon = pOCNW->hIcon;
|
|
|
|
// hide details if no suitable cards available, else show details
|
|
m_fDetailsShown = (0==dwNumOKCards) ? FALSE : TRUE;
|
|
|
|
// prepare critical section for UI routines
|
|
m_pCritSec = new CCriticalSection();
|
|
if (NULL == m_pCritSec)
|
|
{
|
|
return ERROR_OUTOFMEMORY; // TODO: is another errorcode more appropriate?
|
|
}
|
|
|
|
// put dialog on top
|
|
SetForegroundWindow();
|
|
|
|
return SCARD_S_SUCCESS;
|
|
}
|
|
|
|
|
|
void CScInsertDlg::EnableOK(BOOL fEnabled)
|
|
{
|
|
CButton* pBtn = (CButton*)GetDlgItem(IDOK);
|
|
_ASSERTE(NULL != pBtn);
|
|
|
|
pBtn->EnableWindow(fEnabled);
|
|
|
|
//
|
|
// Change prompt text accordingly and set the OK button
|
|
// to be default if it's enabled
|
|
//
|
|
|
|
CString strPrompt;
|
|
|
|
if (fEnabled)
|
|
{
|
|
strPrompt.LoadString(IDS_SC_FOUND);
|
|
|
|
// set <OK> default, remove <Cancel> default
|
|
pBtn->SetButtonStyle(BS_DEFPUSHBUTTON);
|
|
pBtn = (CButton*)GetDlgItem(IDCANCEL);
|
|
_ASSERTE(NULL != pBtn);
|
|
pBtn->SetButtonStyle(BS_PUSHBUTTON);
|
|
pBtn = (CButton*)GetDlgItem(IDC_DETAILS); // details can sometimes get set to default
|
|
_ASSERTE(NULL != pBtn);
|
|
pBtn->SetButtonStyle(BS_PUSHBUTTON);
|
|
|
|
}
|
|
else
|
|
{
|
|
_ASSERTE(!m_strPrompt.IsEmpty());
|
|
strPrompt = m_strPrompt;
|
|
|
|
// remove <OK> default, set <Cancel> default
|
|
pBtn->SetButtonStyle(BS_PUSHBUTTON);
|
|
pBtn = (CButton*)GetDlgItem(IDCANCEL);
|
|
_ASSERTE(NULL != pBtn);
|
|
pBtn->SetButtonStyle(BS_DEFPUSHBUTTON);
|
|
pBtn = (CButton*)GetDlgItem(IDC_DETAILS); // details can sometimes get set to default
|
|
_ASSERTE(NULL != pBtn);
|
|
pBtn->SetButtonStyle(BS_PUSHBUTTON);
|
|
}
|
|
|
|
CWnd* pDlgItem = GetDlgItem(IDC_PROMPT);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
pDlgItem->SetWindowText(strPrompt);
|
|
}
|
|
|
|
|
|
void CScInsertDlg::DisplayError(UINT uiErrorMsg)
|
|
{
|
|
CString strTitle, strMsg;
|
|
|
|
strTitle.LoadString(IDS_SC_TITLE_ERROR);
|
|
strMsg.LoadString(uiErrorMsg);
|
|
|
|
MessageBox(strMsg, strTitle, MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
|
|
void CScInsertDlg::SetSelection(CSCardReaderState* pRdrSt)
|
|
{
|
|
m_pSelectedReader = pRdrSt;
|
|
EnableOK(IsSelectionOK());
|
|
}
|
|
|
|
|
|
BOOL CScInsertDlg::SameCard(CSCardReaderState* p1, CSCardReaderState* p2)
|
|
{
|
|
_ASSERTE(NULL != p1);
|
|
_ASSERTE(NULL != p2);
|
|
|
|
if ((NULL == p1) && (NULL == p2))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if ((NULL == p1) || (NULL == p2))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// same reader & card?
|
|
if ((0 == p1->strReader.Compare(p2->strReader)) &&
|
|
(0 == p1->strCard.Compare(p2->strCard)))
|
|
{
|
|
// no drastic state change?
|
|
if(p1->dwState == p2->dwState)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if(((p1->dwState == SC_SATATUS_AVAILABLE) ||
|
|
(p1->dwState == SC_STATUS_SHARED) ||
|
|
(p1->dwState == SC_STATUS_EXCLUSIVE)) &&
|
|
((p2->dwState == SC_SATATUS_AVAILABLE) ||
|
|
(p2->dwState == SC_STATUS_SHARED) ||
|
|
(p2->dwState == SC_STATUS_EXCLUSIVE)) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScInsertDlg message handlers
|
|
|
|
/*++
|
|
|
|
void ShowHelp:
|
|
|
|
Helper function for OnHelpInfo and OnContextMenu.
|
|
|
|
BOOL OnHelpInfo:
|
|
|
|
Called by the MFC framework when the user hits F1.
|
|
|
|
void OnContextMenu
|
|
|
|
Called by the MFC framework when the user right-clicks.
|
|
|
|
Author:
|
|
|
|
Amanda Matlosz 03/04/1999
|
|
|
|
Note:
|
|
|
|
These three functions work together to provide context-sensitive
|
|
help for the insertdlg. Similar functions are declared for
|
|
CScInsertBar
|
|
|
|
--*/
|
|
void CScInsertDlg::ShowHelp(HWND hWnd, UINT nCommand)
|
|
{
|
|
|
|
::WinHelp(hWnd, _T("SCardDlg.hlp"), nCommand, (DWORD_PTR)(PVOID)g_aHelpIDs_IDD_SCARDDLG1);
|
|
}
|
|
|
|
afx_msg BOOL CScInsertDlg::OnHelpInfo(LPHELPINFO lpHelpInfo)
|
|
{
|
|
_ASSERTE(NULL != lpHelpInfo);
|
|
|
|
ShowHelp((HWND)lpHelpInfo->hItemHandle, HELP_WM_HELP);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
afx_msg void CScInsertDlg::OnContextMenu(CWnd* pWnd, CPoint pt)
|
|
{
|
|
_ASSERTE(NULL != pWnd);
|
|
|
|
ShowHelp(pWnd->m_hWnd, HELP_CONTEXTMENU);
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
void OnReaderStatusChange:
|
|
|
|
This message handler is called by the status thread when smartcard status
|
|
has changed.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
IGNORED BY CALLER. Long indicating status of ResMgr calls.
|
|
|
|
Author:
|
|
|
|
Amanda Matlosz 07/09/1998
|
|
|
|
Note:
|
|
|
|
No formal parameters are declared. These are not used and
|
|
will stop compiler warnings from being generated.
|
|
The long param takes the result of no_service or stopped
|
|
|
|
--*/
|
|
LONG CScInsertDlg::OnReaderStatusChange(UINT uint, LONG lParam)
|
|
{
|
|
// Is monitor still alive?
|
|
|
|
CScStatusMonitor::status status = m_monitor.GetStatus();
|
|
if (CScStatusMonitor::running != status)
|
|
{
|
|
m_pSubDlg->EnableStatusList(FALSE);
|
|
SetSelection(NULL); // JIC
|
|
|
|
// display appropriate error & set m_lLastError
|
|
switch(status)
|
|
{
|
|
case CScStatusMonitor::no_service:
|
|
case CScStatusMonitor::stopped:
|
|
m_lLastError = lParam;
|
|
DisplayError(IDS_SC_RM_ERR);
|
|
break;
|
|
case CScStatusMonitor::no_readers:
|
|
m_lLastError = SCARD_E_NO_READERS_AVAILABLE;
|
|
DisplayError(IDS_SC_NO_READERS);
|
|
break;
|
|
default:
|
|
m_lLastError = SCARD_F_UNKNOWN_ERROR;
|
|
DisplayError(IDS_UNKNOWN_ERROR);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// crit section around member reader/card status array
|
|
_ASSERTE(m_pCritSec);
|
|
if (m_pCritSec)
|
|
{
|
|
m_pCritSec->Lock();
|
|
}
|
|
|
|
// make local copy of recent reader state array,
|
|
// so we know which cards have already been checked
|
|
CSCardReaderStateArray aPreviousReaderState;
|
|
aPreviousReaderState.RemoveAll();
|
|
for (int nCopy = (int)m_aReaderState.GetUpperBound(); nCopy>=0; nCopy--)
|
|
{
|
|
CSCardReaderState* pReader = NULL;
|
|
pReader = new CSCardReaderState(m_aReaderState[nCopy]);
|
|
if (NULL != pReader)
|
|
{
|
|
aPreviousReaderState.Add(pReader);
|
|
}
|
|
}
|
|
|
|
// udpate array from CStatusMonitor
|
|
// check cards that have not been previously checked,
|
|
// & update UI
|
|
|
|
m_monitor.GetReaderStatus(m_aReaderState);
|
|
for (int n = (int)m_aReaderState.GetUpperBound(); n>=0; n--)
|
|
{
|
|
CSCardReaderState* pReader = m_aReaderState[n];
|
|
BOOL fAlreadyChecked = FALSE;
|
|
|
|
// have we checked this card before?
|
|
for (int nPrev = (int)aPreviousReaderState.GetUpperBound();
|
|
(nPrev>=0 && !fAlreadyChecked);
|
|
nPrev--)
|
|
{
|
|
if (SameCard(pReader, aPreviousReaderState[nPrev]))
|
|
{
|
|
pReader->fOK = (aPreviousReaderState[nPrev])->fOK;
|
|
fAlreadyChecked = TRUE;
|
|
}
|
|
}
|
|
|
|
// if this is a new card, or if the card's status has changed
|
|
// drastically since we last looked at it, check it again
|
|
if (!fAlreadyChecked)
|
|
{
|
|
if (NULL != m_pOCNW)
|
|
{
|
|
m_aReaderState[n]->fOK = CheckCardAll(
|
|
m_aReaderState[n],
|
|
m_pOCNW,
|
|
(LPCWSTR)m_mstrAllCards);
|
|
}
|
|
else
|
|
{
|
|
_ASSERTE(NULL != m_pOCNA);
|
|
m_aReaderState[n]->fOK = CheckCardAll(
|
|
m_aReaderState[n],
|
|
m_pOCNA,
|
|
(LPCWSTR)m_mstrAllCards);
|
|
}
|
|
}
|
|
}
|
|
|
|
// the subdialog will handle automatic reader selection
|
|
m_pSubDlg->UpdateStatusList(&m_aReaderState);
|
|
|
|
// clean up
|
|
for (int nX = (int)aPreviousReaderState.GetUpperBound(); nX>=0; nX--)
|
|
{
|
|
delete aPreviousReaderState[nX];
|
|
}
|
|
aPreviousReaderState.RemoveAll();
|
|
|
|
// end crit section
|
|
if (m_pCritSec)
|
|
{
|
|
m_pCritSec->Unlock();
|
|
}
|
|
|
|
}
|
|
|
|
return (long)SCARD_S_SUCCESS; // there's no one to receive this.
|
|
}
|
|
|
|
|
|
void CScInsertDlg::OnDetails()
|
|
{
|
|
//
|
|
// If the details are currently shown, hide them...
|
|
// otherwise, show them.
|
|
//
|
|
CRect rectWin;
|
|
|
|
GetWindowRect(&rectWin);
|
|
|
|
CRect rectButtonBottom;
|
|
|
|
CString strDetailsCaption;
|
|
|
|
//
|
|
// Determine the new height of the dialog & resize
|
|
//
|
|
|
|
int nNewHeight = 0;
|
|
if (m_fDetailsShown)
|
|
{
|
|
nNewHeight = m_SmallHeight;
|
|
strDetailsCaption.LoadString(IDS_DETAILS_SHOW);
|
|
}
|
|
else
|
|
{
|
|
nNewHeight = m_BigHeight;
|
|
strDetailsCaption.LoadString(IDS_DETAILS_HIDE);
|
|
}
|
|
|
|
ScreenToClient(&rectButtonBottom);
|
|
rectWin.bottom = rectWin.top + nNewHeight;
|
|
|
|
SetWindowPos(NULL,
|
|
rectWin.left,
|
|
rectWin.top,
|
|
rectWin.Width(),
|
|
rectWin.Height(),
|
|
SWP_NOMOVE | SWP_NOZORDER);
|
|
|
|
//
|
|
// change captions, move buttons, show or hide the details section
|
|
//
|
|
|
|
m_btnDetails.SetWindowText(strDetailsCaption);
|
|
|
|
MoveButton(IDC_DETAILS, nNewHeight - m_yMargin);
|
|
MoveButton(IDOK, nNewHeight - m_yMargin);
|
|
MoveButton(IDCANCEL, nNewHeight - m_yMargin);
|
|
|
|
ToggleSubDialog();
|
|
|
|
//
|
|
// remember our new state
|
|
//
|
|
|
|
m_fDetailsShown = !m_fDetailsShown;
|
|
}
|
|
|
|
|
|
BOOL CScInsertDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
//
|
|
// Initialize bits to query RM; if these fail, there's no point to go on
|
|
// but the user should see an error message.
|
|
//
|
|
|
|
// kick off CSCStatusMonitor
|
|
m_lLastError = m_monitor.Start(m_hWnd, WM_READERSTATUSCHANGE);
|
|
|
|
// if not running or no readers available
|
|
CScStatusMonitor::status status = m_monitor.GetStatus();
|
|
|
|
if (SCARD_S_SUCCESS != m_lLastError)
|
|
{
|
|
switch(status)
|
|
{
|
|
case CScStatusMonitor::no_service:
|
|
DisplayError(IDS_SC_RM_ERR);
|
|
break;
|
|
case CScStatusMonitor::no_readers:
|
|
// DisplayError(IDS_SC_NO_READERS); // Bug 15742 -> will die quietly (no UI)
|
|
break;
|
|
case CScStatusMonitor::running:
|
|
_ASSERTE(FALSE); // How can this be running if an error was returned??????
|
|
// no break; go ahead an report an 'unknown error'
|
|
default:
|
|
DisplayError(IDS_UNKNOWN_ERROR);
|
|
break;
|
|
}
|
|
|
|
PostMessage(WM_CLOSE, 0, 0);
|
|
return TRUE;
|
|
}
|
|
_ASSERTE(status == CScStatusMonitor::running);
|
|
|
|
//
|
|
// Determine constant offsets for resizing window (on details)
|
|
//
|
|
|
|
CRect rectWin, rectDlgItem;
|
|
GetWindowRect(&rectWin);
|
|
|
|
m_SmallHeight = rectWin.Height();
|
|
|
|
CWnd* pDlgItem = GetDlgItem(IDOK);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
pDlgItem->GetWindowRect(&rectDlgItem);
|
|
ScreenToClient(rectDlgItem);
|
|
|
|
m_yMargin = m_SmallHeight - rectDlgItem.bottom;
|
|
|
|
pDlgItem = GetDlgItem(IDC_BUTTON_BOTTOM);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
pDlgItem->GetWindowRect(&rectDlgItem);
|
|
ScreenToClient(rectDlgItem);
|
|
|
|
m_BigHeight = rectDlgItem.bottom + m_yMargin;
|
|
|
|
//
|
|
// Add user-provided or ReaderLoaded icon
|
|
//
|
|
|
|
if (NULL == m_hIcon)
|
|
{
|
|
m_hIcon = AfxGetApp()->LoadIcon(IDI_SC_READERLOADED_V2);
|
|
}
|
|
_ASSERTE(NULL != m_hIcon);
|
|
|
|
pDlgItem = GetDlgItem(IDC_USERICON);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
|
|
pDlgItem->SetIcon(m_hIcon, TRUE); // TRUE: 32x32 icon
|
|
|
|
//
|
|
// Add other User-Customization bits
|
|
//
|
|
|
|
if (!m_strTitle.IsEmpty())
|
|
{
|
|
SetWindowText(m_strTitle);
|
|
}
|
|
|
|
if (m_strPrompt.IsEmpty())
|
|
{
|
|
// Use the default prompt text.
|
|
m_strPrompt.LoadString(IDS_SC_PROMPT_ANYCARD);
|
|
}
|
|
pDlgItem = GetDlgItem(IDC_PROMPT);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
pDlgItem->SetWindowText(m_strPrompt);
|
|
|
|
// by default, <OK> is not enabled (subdlg's OnInitDlg might change that)
|
|
EnableOK(FALSE);
|
|
|
|
//
|
|
// Set HELP ID(s) for context help
|
|
//
|
|
|
|
pDlgItem = GetDlgItem(IDC_DETAILS);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
pDlgItem->SetWindowContextHelpId(IDH_DLG1_DETAILS_BTN);
|
|
|
|
//
|
|
// Add CScInsertBar (actually, a CDialog-derivative) to our dialog
|
|
//
|
|
|
|
pDlgItem = GetDlgItem(IDC_DLGBAR);
|
|
_ASSERTE(NULL != pDlgItem);
|
|
pDlgItem->GetWindowRect(&rectDlgItem);
|
|
ScreenToClient(rectDlgItem);
|
|
|
|
m_pSubDlg = new CScInsertBar(this);
|
|
_ASSERTE(NULL != m_pSubDlg);
|
|
if (NULL == m_pSubDlg)
|
|
{
|
|
m_lLastError = ERROR_OUTOFMEMORY;
|
|
PostMessage(WM_CLOSE, 0, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
m_pSubDlg->Create(IDD_SCARDDLG_BAR, this);
|
|
m_pSubDlg->SetWindowPos(NULL,
|
|
rectDlgItem.left,
|
|
rectDlgItem.top,
|
|
0,
|
|
0,
|
|
SWP_NOSIZE | SWP_NOACTIVATE); // TODO: SWP_NOZORDER ??
|
|
|
|
//
|
|
// Set the dialog to alter itself to match how it was called
|
|
//
|
|
|
|
m_fDetailsShown = !m_fDetailsShown;
|
|
OnDetails();
|
|
|
|
if (m_fDetailsShown)
|
|
{
|
|
return FALSE; // focus should be set to list control
|
|
}
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
|
|
void CScInsertDlg::MoveButton(UINT nID, int newBottom)
|
|
{
|
|
CWnd* pBtn = GetDlgItem(nID);
|
|
_ASSERTE(NULL != pBtn);
|
|
|
|
CRect rect;
|
|
pBtn->GetWindowRect(&rect);
|
|
ScreenToClient(&rect);
|
|
rect.top = newBottom - rect.Height();
|
|
|
|
pBtn->SetWindowPos(NULL,
|
|
rect.left,
|
|
rect.top,
|
|
0,
|
|
0,
|
|
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
|
}
|
|
|
|
|
|
void CScInsertDlg::ToggleSubDialog()
|
|
{
|
|
//
|
|
// All you need to do to toggle the sub dialog's accessibility
|
|
// is to hide&disable or show&enable the window.
|
|
//
|
|
|
|
if (m_fDetailsShown)
|
|
{
|
|
m_pSubDlg->ShowWindow(SW_HIDE);
|
|
m_pSubDlg->EnableWindow(FALSE);
|
|
}
|
|
else
|
|
{
|
|
m_pSubDlg->ShowWindow(SW_SHOW);
|
|
m_pSubDlg->EnableWindow(TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL CScInsertDlg::DestroyWindow()
|
|
{
|
|
if (NULL != m_pSubDlg)
|
|
{
|
|
m_pSubDlg->DestroyWindow();
|
|
delete m_pSubDlg;
|
|
}
|
|
|
|
return CDialog::DestroyWindow();
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
void OnOK:
|
|
|
|
Handle user's <OK>, error if can't complete
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Author:
|
|
|
|
Amanda Matlosz 4/28/98
|
|
--*/
|
|
void CScInsertDlg::OnOK()
|
|
{
|
|
USES_CONVERSION;
|
|
|
|
// Must have something selected to exit
|
|
|
|
if (NULL == m_pSelectedReader || m_pSelectedReader->strCard.IsEmpty())
|
|
{
|
|
DisplayError(IDS_SC_SELECT);
|
|
return;
|
|
}
|
|
|
|
// Must have selected something we're looking for...
|
|
|
|
if (!(m_pSelectedReader->fOK))
|
|
{
|
|
DisplayError(IDS_SC_NOMATCH);
|
|
return;
|
|
}
|
|
|
|
// Call the correct method to set the *real* card selection
|
|
|
|
if(NULL != m_pOCNA)
|
|
{
|
|
|
|
LPSTR szCard = W2A(m_pSelectedReader->strCard);
|
|
LPSTR szReader = W2A(m_pSelectedReader->strReader);
|
|
|
|
m_lLastError = SetFinalCardSelection(szReader, szCard, m_pOCNA);
|
|
}
|
|
else
|
|
{
|
|
_ASSERTE(NULL != m_pOCNW);
|
|
|
|
LPWSTR szCard = m_pSelectedReader->strCard.GetBuffer(1);
|
|
LPWSTR szReader = m_pSelectedReader->strReader.GetBuffer(1);
|
|
|
|
m_lLastError = SetFinalCardSelection(szReader, szCard, m_pOCNW);
|
|
|
|
m_pSelectedReader->strCard.ReleaseBuffer();
|
|
m_pSelectedReader->strReader.ReleaseBuffer();
|
|
}
|
|
|
|
if (SCARD_S_SUCCESS != m_lLastError)
|
|
{
|
|
DisplayError(IDS_SC_CONNECT_FAILED); // Either connect failed or out of memory - close enough.
|
|
return;
|
|
}
|
|
|
|
CDialog::OnOK();
|
|
}
|