1930 lines
54 KiB
C++
1930 lines
54 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 1993-1996 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// MODULE: spoolui.cpp
|
|
//
|
|
// PURPOSE: Implements the spooler UI dialogs.
|
|
//
|
|
|
|
#include "pch.hxx"
|
|
#include "resource.h"
|
|
#include "spoolui.h"
|
|
#include "goptions.h"
|
|
#include "imnact.h"
|
|
#include "thormsgs.h"
|
|
#include "shlwapip.h"
|
|
#include "spengine.h"
|
|
#include "ourguid.h"
|
|
#include "demand.h"
|
|
#include "menures.h"
|
|
#include "multiusr.h"
|
|
|
|
ASSERTDATA
|
|
|
|
static const char c_szWndProc[] = "WndProc";
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::CSpoolerDlg()
|
|
//
|
|
// PURPOSE: Initializes the member variables of the spooler ui object.
|
|
//
|
|
CSpoolerDlg::CSpoolerDlg()
|
|
{
|
|
m_cRef = 1;
|
|
|
|
m_pBindCtx = NULL;
|
|
|
|
m_hwnd = NULL;
|
|
m_hwndOwner = NULL;
|
|
m_hwndEvents = NULL;
|
|
m_hwndErrors = NULL;
|
|
|
|
InitializeCriticalSection(&m_cs);
|
|
|
|
m_himlImages = NULL;
|
|
|
|
m_fTack = FALSE;
|
|
m_iTab = 0;
|
|
m_fIdle = FALSE;
|
|
m_fErrors = FALSE;
|
|
m_fShutdown = FALSE;
|
|
m_fSaveSize = FALSE;
|
|
|
|
m_fExpanded = TRUE;
|
|
ZeroMemory(&m_rcDlg, sizeof(RECT));
|
|
m_cyCollapsed = 0;
|
|
|
|
m_szCount[0] = '\0';
|
|
|
|
m_hIcon=NULL;
|
|
m_hIconSm=NULL;
|
|
m_dwIdentCookie = 0;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::~CSpoolerDlg()
|
|
//
|
|
// PURPOSE: Frees any resources allocated during the life of the class.
|
|
//
|
|
CSpoolerDlg::~CSpoolerDlg()
|
|
{
|
|
GoIdle(TRUE, FALSE, FALSE);
|
|
|
|
if (m_hwnd && IsWindow(m_hwnd))
|
|
DestroyWindow(m_hwnd);
|
|
if (m_himlImages)
|
|
ImageList_Destroy(m_himlImages);
|
|
SafeRelease(m_pBindCtx);
|
|
DeleteCriticalSection(&m_cs);
|
|
if (m_hIcon)
|
|
SideAssert(DestroyIcon(m_hIcon));
|
|
if (m_hIconSm)
|
|
SideAssert(DestroyIcon(m_hIconSm));
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::Init()
|
|
//
|
|
// PURPOSE: Creates the spooler dialog. The dialog is not initially
|
|
// visible.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> hwndOwner - Handle of the window to parent the dialog to.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK - The dialog was created and initialized
|
|
// E_OUTOFMEMORY - The dialog could not be created
|
|
// E_INVALIDARG - Think about it.
|
|
//
|
|
HRESULT CSpoolerDlg::Init(HWND hwndOwner)
|
|
{
|
|
int iReturn = -1;
|
|
HWND hwnd, hwndActive;
|
|
|
|
// Verify the arguments
|
|
if (!IsWindow(hwndOwner))
|
|
return (E_INVALIDARG);
|
|
|
|
// Make a copy
|
|
m_hwndOwner = hwndOwner;
|
|
|
|
// Invoke the dialog
|
|
hwndActive = GetForegroundWindow();
|
|
|
|
hwnd = CreateDialogParam(g_hLocRes, MAKEINTRESOURCE(iddSpoolerDlg), m_hwndOwner,
|
|
SpoolerDlgProc, (LPARAM) this);
|
|
|
|
if (hwndActive != GetForegroundWindow())
|
|
SetForegroundWindow(hwndActive);
|
|
|
|
// Set the dialog icon
|
|
m_hIcon = (HICON) LoadImage(g_hLocRes, MAKEINTRESOURCE(idiMail), IMAGE_ICON, 32, 32, 0);
|
|
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)m_hIcon);
|
|
m_hIconSm = (HICON) LoadImage(g_hLocRes, MAKEINTRESOURCE(idiMail), IMAGE_ICON, 16, 16, 0);
|
|
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)m_hIconSm);
|
|
|
|
SetTaskCounts(0, 0);
|
|
|
|
// Register with identity manager
|
|
SideAssert(SUCCEEDED(MU_RegisterIdentityNotifier((IUnknown *)(ISpoolerUI *)this, &m_dwIdentCookie)));
|
|
|
|
return (IsWindow(hwnd) ? S_OK : E_OUTOFMEMORY);
|
|
}
|
|
|
|
|
|
HRESULT CSpoolerDlg::QueryInterface(REFIID riid, LPVOID *ppvObj)
|
|
{
|
|
if (NULL == *ppvObj)
|
|
return (E_INVALIDARG);
|
|
|
|
*ppvObj = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
*ppvObj = (LPVOID)(IUnknown *)(ISpoolerUI *) this;
|
|
|
|
else if (IsEqualIID(riid, IID_ISpoolerUI))
|
|
*ppvObj = (LPVOID)(ISpoolerUI *) this;
|
|
|
|
else if (IsEqualIID(riid, IID_IIdentityChangeNotify))
|
|
*ppvObj = (LPVOID)(IIdentityChangeNotify *) this;
|
|
|
|
if (NULL == *ppvObj)
|
|
return (E_NOINTERFACE);
|
|
|
|
AddRef();
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
ULONG CSpoolerDlg::AddRef(void)
|
|
{
|
|
m_cRef++;
|
|
return (m_cRef);
|
|
}
|
|
|
|
|
|
ULONG CSpoolerDlg::Release(void)
|
|
{
|
|
ULONG cRefT = --m_cRef;
|
|
|
|
if (0 == m_cRef)
|
|
delete this;
|
|
|
|
return (cRefT);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::RegisterBindContext()
|
|
//
|
|
// PURPOSE: Allows the spooler engine to provide us with a bind context
|
|
// interface for us to call back into.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> pBindCtx - Pointer to the engine's bind context interface
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::RegisterBindContext(ISpoolerBindContext *pBindCtx)
|
|
{
|
|
if (NULL == pBindCtx)
|
|
return (E_INVALIDARG);
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
m_pBindCtx = pBindCtx;
|
|
m_pBindCtx->AddRef();
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::InsertEvent()
|
|
//
|
|
// PURPOSE: Allows a caller to insert an event into our event list UI.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> eid - Event ID for this new event
|
|
// <in> pszDescription - Description of the event
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// E_OUTOFMEMORY
|
|
//
|
|
HRESULT CSpoolerDlg::InsertEvent(EVENTID eid, LPCTSTR pszDescription,
|
|
LPCWSTR pwszConnection)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
LV_ITEM lvi;
|
|
int iItem = -1;
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
|
|
// Verify the arguments
|
|
if (0 == pszDescription)
|
|
return (E_INVALIDARG);
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Make sure the listview has been initialized
|
|
if (!IsWindow(m_hwndEvents))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
// Insert the item into the listview
|
|
ZeroMemory(&lvi, sizeof(LV_ITEM));
|
|
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
|
|
lvi.iItem = ListView_GetItemCount(m_hwndEvents);
|
|
lvi.iSubItem = 0;
|
|
lvi.lParam = (LPARAM) eid;
|
|
lvi.iImage = IMAGE_BLANK;
|
|
|
|
if (IS_INTRESOURCE(pszDescription))
|
|
{
|
|
AthLoadString(PtrToUlong(pszDescription), szRes, ARRAYSIZE(szRes));
|
|
lvi.pszText = szRes;
|
|
}
|
|
else
|
|
lvi.pszText = (LPTSTR) pszDescription;
|
|
|
|
iItem = ListView_InsertItem(m_hwndEvents, &lvi);
|
|
Assert(iItem != -1);
|
|
if (iItem == -1)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
{
|
|
LVITEMW lviw = {0};
|
|
|
|
lviw.iSubItem = 2;
|
|
lviw.pszText = (LPWSTR)pwszConnection;
|
|
SendMessage(m_hwndEvents, LVM_SETITEMTEXTW, (WPARAM)iItem, (LPARAM)&lviw);
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::InsertError()
|
|
//
|
|
// PURPOSE: Allows a task to insert an error into our error list UI.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> eid - The event ID of the event that had the error.
|
|
// <in> pszError - Description of the error.
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// E_OUTOFMEMORY
|
|
//
|
|
HRESULT CSpoolerDlg::InsertError(EVENTID eid, LPCTSTR pszError)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LBDATA *pData = NULL;
|
|
int nItem;
|
|
HDC hdc;
|
|
HFONT hfont;
|
|
|
|
// Verify the arguments
|
|
if (0 == pszError)
|
|
return (E_INVALIDARG);
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Make sure the listview has been initialized
|
|
if (!IsWindow(m_hwndErrors))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
// Allocate a struct for the item data
|
|
if (!MemAlloc((LPVOID *) &pData, sizeof(LBDATA)))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
pData->eid = eid;
|
|
|
|
// Check to see if we need to load the string ourselves
|
|
if (IS_INTRESOURCE(pszError))
|
|
{
|
|
pData->pszText = AthLoadString(PtrToUlong(pszError), 0, 0);
|
|
}
|
|
else
|
|
pData->pszText = PszDupA(pszError);
|
|
|
|
// Get the size of the string
|
|
hfont = (HFONT) SendMessage(m_hwnd, WM_GETFONT, 0, 0);
|
|
|
|
hdc = GetDC(m_hwndErrors);
|
|
SelectFont(hdc, hfont);
|
|
|
|
SetRect(&(pData->rcText), 0, 0, m_cxErrors - BULLET_WIDTH - 4, 0);
|
|
// bug #47453, add DT_INTERNAL flag so that on FE platform (PRC and TC)
|
|
// two list items is not overlapping.
|
|
DrawText(hdc, pData->pszText, -1, &(pData->rcText), DT_CALCRECT | DT_WORDBREAK | DT_INTERNAL);
|
|
ReleaseDC(m_hwndErrors, hdc);
|
|
|
|
pData->rcText.bottom += 4;
|
|
|
|
// Add the item data
|
|
nItem = ListBox_AddItemData(m_hwndErrors, pData);
|
|
}
|
|
|
|
exit:
|
|
LeaveCriticalSection(&m_cs);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::UpdateEventState()
|
|
//
|
|
// PURPOSE: Allows a task to update the description and state of an event.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> eid - ID of the event to update
|
|
// <in> nImage - Image to display for the item. If this is -1,
|
|
// the image is not changed.
|
|
// <in> pszDescription - Description for the item. If this is NULL, the
|
|
// description is not changed.
|
|
// <in> pszStatus - Status of the item. If this is NULL, the status
|
|
// is not changed.
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// SP_E_EVENTNOTFOUND
|
|
// E_UNEXPECTED
|
|
//
|
|
HRESULT CSpoolerDlg::UpdateEventState(EVENTID eid, INT nImage,
|
|
LPCTSTR pszDescription, LPCTSTR pszStatus)
|
|
{
|
|
LV_ITEM lvi;
|
|
LV_FINDINFO lvfi;
|
|
int iItem = -1;
|
|
BOOL fSuccess = FALSE;
|
|
HRESULT hr = S_OK;
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
ZeroMemory(&lvi, sizeof(LV_ITEM));
|
|
|
|
// See if we're initialized
|
|
if (!IsWindow(m_hwndEvents))
|
|
{
|
|
hr = SP_E_UNINITIALIZED;
|
|
goto exit;
|
|
}
|
|
|
|
// Start by finding the event in our list
|
|
lvfi.flags = LVFI_PARAM;
|
|
lvfi.psz = 0;
|
|
lvfi.lParam = eid;
|
|
|
|
iItem = ListView_FindItem(m_hwndEvents, -1, &lvfi);
|
|
if (-1 == iItem)
|
|
{
|
|
hr = SP_E_EVENTNOTFOUND;
|
|
goto exit;
|
|
}
|
|
|
|
// Update the image and description
|
|
lvi.mask = 0;
|
|
lvi.iItem = iItem;
|
|
lvi.iSubItem = 0;
|
|
|
|
// Set up the image info
|
|
if (-1 != nImage)
|
|
{
|
|
lvi.mask = LVIF_IMAGE;
|
|
lvi.iImage = nImage;
|
|
}
|
|
|
|
// Set up the description text
|
|
if (NULL != pszDescription)
|
|
{
|
|
// Check to see if we need to load the string ourselves
|
|
if (IS_INTRESOURCE(pszDescription))
|
|
{
|
|
AthLoadString(PtrToUlong(pszDescription), szRes, ARRAYSIZE(szRes));
|
|
lvi.pszText = szRes;
|
|
}
|
|
else
|
|
lvi.pszText = (LPTSTR) pszDescription;
|
|
|
|
lvi.mask |= LVIF_TEXT;
|
|
}
|
|
|
|
if (lvi.mask)
|
|
fSuccess = ListView_SetItem(m_hwndEvents, &lvi);
|
|
|
|
// Update the status
|
|
if (NULL != pszStatus)
|
|
{
|
|
// Check to see if we need to load the string ourselves
|
|
if (IS_INTRESOURCE(pszStatus))
|
|
{
|
|
AthLoadString(PtrToUlong(pszStatus), szRes, ARRAYSIZE(szRes));
|
|
lvi.pszText = szRes;
|
|
}
|
|
else
|
|
lvi.pszText = (LPTSTR) pszStatus;
|
|
|
|
lvi.mask = LVIF_TEXT;
|
|
lvi.iSubItem = 1;
|
|
|
|
ListView_SetItemText(m_hwndEvents, lvi.iItem, 1, lvi.pszText); /* fSuccess = fSuccess && */
|
|
}
|
|
|
|
hr = fSuccess ? S_OK : E_UNEXPECTED;
|
|
|
|
exit:
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::SetProgressRange()
|
|
//
|
|
// PURPOSE: Resets the progress bar to zero, and then sets the upper bound
|
|
// to the specified amount.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> wMax - New maximum range for the progress bar
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::SetProgressRange(WORD wMax)
|
|
{
|
|
HWND hwndProg = GetDlgItem(m_hwnd, IDC_SP_PROGRESS_BAR);
|
|
HRESULT hr = S_OK;
|
|
|
|
if (wMax == 0)
|
|
return (E_INVALIDARG);
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Make sure we have a progress bar
|
|
if (!IsWindow(hwndProg))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
// Reset the progress bar
|
|
SendMessage(hwndProg, PBM_SETPOS, 0, 0);
|
|
|
|
// Set the new range
|
|
SendMessage(hwndProg, PBM_SETRANGE, 0, MAKELPARAM(0, wMax));
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::IncrementProgress()
|
|
//
|
|
// PURPOSE: Increments the progress bar by a specified amount.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> wDelta - Amount to increment the progress bar by
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::IncrementProgress(WORD wDelta)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_PROGRESS_BAR, PBM_DELTAPOS, wDelta, 0);
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::SetProgressPosition()
|
|
//
|
|
// PURPOSE: Sets the progress bar to a specific position.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> wPos - Position to set progress bar to
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::SetProgressPosition(WORD wPos)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (wPos < 0)
|
|
hr = E_INVALIDARG;
|
|
else if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_PROGRESS_BAR, PBM_SETPOS, wPos, 0);
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::SetGeneralProgress()
|
|
//
|
|
// PURPOSE: Allows the caller to update the general progress text.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> pszProgress - New progress string
|
|
//
|
|
// RETURN VALUE:
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::SetGeneralProgress(LPCTSTR pszProgress)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
if (pszProgress)
|
|
SetDlgItemText(m_hwnd, IDC_SP_GENERAL_PROG, pszProgress);
|
|
else
|
|
SetDlgItemText(m_hwnd, IDC_SP_GENERAL_PROG, _T(""));
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::SetSpecificProgress()
|
|
//
|
|
// PURPOSE: Allows the caller to update the specific progress text.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> pszProgress - New progress string
|
|
//
|
|
// RETURN VALUE:
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::SetSpecificProgress(LPCTSTR pszProgress)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
if (IS_INTRESOURCE(pszProgress))
|
|
{
|
|
AthLoadString(PtrToUlong(pszProgress), szRes, ARRAYSIZE(szRes));
|
|
pszProgress = szRes;
|
|
}
|
|
|
|
if (pszProgress)
|
|
SetDlgItemText(m_hwnd, IDC_SP_SPECIFIC_PROG, pszProgress);
|
|
else
|
|
SetDlgItemText(m_hwnd, IDC_SP_SPECIFIC_PROG, _T(""));
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::SetAnimation()
|
|
//
|
|
// PURPOSE: Allows the caller to choose which animation is playing
|
|
//
|
|
// PARAMETERS:
|
|
// <in> nAnimationID - New resource id for the animation
|
|
// <in> fPlay - TRUE if we should start animating it.
|
|
//
|
|
// RETURN VALUE:
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::SetAnimation(int nAnimationID, BOOL fPlay)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HWND hwndAni;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
#ifndef _WIN64
|
|
if (!IsWindow(m_hwnd) || !IsWindow(GetDlgItem(m_hwnd, IDC_SP_ANIMATE)))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
hwndAni = GetDlgItem(m_hwnd, IDC_SP_ANIMATE);
|
|
Animate_Close(hwndAni);
|
|
|
|
if (IsWindow(m_hwnd) && IsWindow(GetDlgItem(m_hwnd, IDC_SP_ANIMATE)))
|
|
{
|
|
Animate_OpenEx(hwndAni, g_hLocRes, MAKEINTRESOURCE(nAnimationID));
|
|
|
|
if (fPlay)
|
|
Animate_Play(hwndAni, 0, -1, -1);
|
|
}
|
|
}
|
|
#endif // _WIN64
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::EnsureVisible()
|
|
//
|
|
// PURPOSE: Ensures that the specified event is visible within the listview
|
|
//
|
|
// PARAMETERS:
|
|
// <in> eid - Event ID to make sure is visible
|
|
//
|
|
// RETURN VALUE:
|
|
// SP_E_UNINITIALIZED
|
|
// SP_E_EVENTNOTFOUND
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::EnsureVisible(EVENTID eid)
|
|
{
|
|
LV_FINDINFO lvfi;
|
|
int iItem = -1;
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// See if we're initialized
|
|
if (!IsWindow(m_hwndEvents))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
// Start by finding the event in our list
|
|
lvfi.flags = LVFI_PARAM;
|
|
lvfi.psz = 0;
|
|
lvfi.lParam = eid;
|
|
|
|
iItem = ListView_FindItem(m_hwndEvents, -1, &lvfi);
|
|
|
|
// Now tell the listview to make sure it's visible
|
|
if (-1 != iItem)
|
|
ListView_EnsureVisible(m_hwndEvents, iItem, FALSE);
|
|
|
|
hr = (iItem == -1) ? SP_E_EVENTNOTFOUND : S_OK;
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::ShowWindow()
|
|
//
|
|
// PURPOSE: Shows or hides the spooler dialog
|
|
//
|
|
// PARAMETERS:
|
|
// <in> nCmdShow - This is the same as the ShowWindow() API
|
|
//
|
|
// RETURN VALUE:
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::ShowWindow(int nCmdShow)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
{
|
|
::ShowWindow(m_hwnd, nCmdShow);
|
|
if (m_pBindCtx)
|
|
m_pBindCtx->OnUIChange(nCmdShow == SW_SHOW);
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::StartDelivery()
|
|
//
|
|
// PURPOSE: Tells the dialog the delivery has begun.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
// SP_E_UNINITIALIZED
|
|
//
|
|
HRESULT CSpoolerDlg::StartDelivery(void)
|
|
{
|
|
HRESULT hr = SP_E_UNINITIALIZED;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (IsWindow(m_hwnd))
|
|
{
|
|
//Animate_Play(GetDlgItem(m_hwnd, IDC_SP_ANIMATE), 0, -1, -1);
|
|
|
|
TabCtrl_SetCurSel(GetDlgItem(m_hwnd, IDC_SP_TABS), TAB_TASKS);
|
|
OnTabChange(0);
|
|
|
|
ToggleStatics(FALSE);
|
|
SetDlgItemText(m_hwnd, IDC_SP_GENERAL_PROG, _T(""));
|
|
SetDlgItemText(m_hwnd, IDC_SP_SPECIFIC_PROG, _T(""));
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_STOP), FALSE);
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::ClearEvents()
|
|
//
|
|
// PURPOSE: Clears any events and errors out of the listviews.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
// SP_E_UNINITIALIZED
|
|
//
|
|
HRESULT CSpoolerDlg::ClearEvents(void)
|
|
{
|
|
HRESULT hr = SP_E_UNINITIALIZED;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (IsWindow(m_hwnd))
|
|
{
|
|
m_fErrors = FALSE;
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_STOP), FALSE);
|
|
ListView_DeleteAllItems(m_hwndEvents);
|
|
ListBox_ResetContent(m_hwndErrors);
|
|
hr = S_OK;
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
HRESULT CSpoolerDlg::SetTaskCounts(DWORD cSucceeded, DWORD cTotal)
|
|
{
|
|
TCHAR szBuf[CCHMAX_STRINGRES];
|
|
HRESULT hr = SP_E_UNINITIALIZED;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (IsWindow(m_hwnd))
|
|
{
|
|
wnsprintf(szBuf, ARRAYSIZE(szBuf), m_szCount, cSucceeded, cTotal);
|
|
SetDlgItemText(m_hwnd, IDC_SP_OVERALL_STATUS, szBuf);
|
|
hr = S_OK;
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
HRESULT CSpoolerDlg::AreThereErrors(void)
|
|
{
|
|
EnterCriticalSection(&m_cs);
|
|
HRESULT hr = (m_fErrors ? S_OK : S_FALSE);
|
|
LeaveCriticalSection(&m_cs);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSpoolerDlg::Shutdown(void)
|
|
{
|
|
CHAR szRes[255];
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
m_fShutdown = TRUE;
|
|
|
|
if (IsWindow(m_hwnd))
|
|
{
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_STOP), FALSE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_MINIMIZE), TRUE);
|
|
|
|
LoadString(g_hLocRes, idsClose, szRes, ARRAYSIZE(szRes));
|
|
SetDlgItemText(m_hwnd, IDC_SP_MINIMIZE, szRes);
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::GoIdle()
|
|
//
|
|
// PURPOSE: Tells the dialog the delivery has ended.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> fErrors - TRUE if errors occured during the download.
|
|
//
|
|
// RETURN VALUE:
|
|
// S_OK
|
|
// SP_E_UNINITIALIZED
|
|
//
|
|
HRESULT CSpoolerDlg::GoIdle(BOOL fErrors, BOOL fShutdown, BOOL fNoSync)
|
|
{
|
|
HRESULT hr = SP_E_UNINITIALIZED;
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (IsWindow(m_hwnd))
|
|
{
|
|
// Stop the animation
|
|
#ifndef _WIN64
|
|
Animate_Close(GetDlgItem(m_hwnd, IDC_SP_ANIMATE));
|
|
#endif
|
|
hr = S_OK;
|
|
|
|
ToggleStatics(TRUE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_STOP), FALSE);
|
|
|
|
if (ISFLAGSET(fErrors, SPSTATE_CANCEL))
|
|
{
|
|
m_fErrors = TRUE;
|
|
ExpandCollapse(TRUE);
|
|
TabCtrl_SetCurSel(GetDlgItem(m_hwnd, IDC_SP_TABS), TAB_TASKS);
|
|
OnTabChange(0);
|
|
|
|
AthLoadString(idsSpoolerUserCancel, szRes, ARRAYSIZE(szRes));
|
|
SetDlgItemText(m_hwnd, IDC_SP_IDLETEXT, szRes);
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_IDLEICON, STM_SETICON,
|
|
(WPARAM) LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiError)), 0);
|
|
}
|
|
// Also if there were errors, we should switch to the error page
|
|
else if (fErrors)
|
|
{
|
|
m_fErrors = TRUE;
|
|
ExpandCollapse(TRUE);
|
|
TabCtrl_SetCurSel(GetDlgItem(m_hwnd, IDC_SP_TABS), TAB_ERRORS);
|
|
OnTabChange(0);
|
|
|
|
AthLoadString(idsSpoolerIdleErrors, szRes, ARRAYSIZE(szRes));
|
|
SetDlgItemText(m_hwnd, IDC_SP_IDLETEXT, szRes);
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_IDLEICON, STM_SETICON,
|
|
(WPARAM) LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiError)), 0);
|
|
}
|
|
else
|
|
{
|
|
AthLoadString(idsSpoolerIdle, szRes, ARRAYSIZE(szRes));
|
|
SetDlgItemText(m_hwnd, IDC_SP_IDLETEXT, szRes);
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_IDLEICON, STM_SETICON,
|
|
(WPARAM) LoadIcon(g_hLocRes, MAKEINTRESOURCE(idiMailNews)), 0);
|
|
|
|
if (fNoSync)
|
|
AthMessageBoxW(m_hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsNothingToSync), NULL, MB_OK | MB_ICONEXCLAMATION);
|
|
|
|
// Determine if we need to hide the dialog
|
|
UINT state = (UINT) SendDlgItemMessage(m_hwnd, IDC_SP_TOOLBAR, TB_GETSTATE, IDC_SP_TACK, 0);
|
|
if (!(state & TBSTATE_CHECKED))
|
|
ShowWindow(SW_HIDE);
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::IsDialogMessage()
|
|
//
|
|
// PURPOSE: Allows the dialog to retrieve messages from the message loop.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> pMsg - Pointer to the message for us to examine.
|
|
//
|
|
// RETURN VALUE:
|
|
// Returns S_OK if we eat the message, S_FALSE otherwise.
|
|
//
|
|
HRESULT CSpoolerDlg::IsDialogMessage(LPMSG pMsg)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fEaten = FALSE;
|
|
BOOL fBack = FALSE;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Intended for modeless timeout dialog running on this thread?
|
|
HWND hwndTimeout = (HWND)TlsGetValue(g_dwTlsTimeout);
|
|
if (hwndTimeout && ::IsDialogMessage(hwndTimeout, pMsg))
|
|
return(S_OK);
|
|
|
|
if (pMsg->message == WM_KEYDOWN && (GetAsyncKeyState(VK_CONTROL) < 0))
|
|
{
|
|
switch (pMsg->wParam)
|
|
{
|
|
case VK_TAB:
|
|
fBack = GetAsyncKeyState(VK_SHIFT) < 0;
|
|
break;
|
|
|
|
case VK_PRIOR: // VK_PAGE_UP
|
|
case VK_NEXT: // VK_PAGE_DOWN
|
|
fBack = (pMsg->wParam == VK_PRIOR);
|
|
break;
|
|
|
|
default:
|
|
goto NoKeys;
|
|
}
|
|
|
|
int iCur = TabCtrl_GetCurSel(GetDlgItem(m_hwnd, IDC_SP_TABS));
|
|
|
|
// tab in reverse if shift is down
|
|
if (fBack)
|
|
iCur += (TAB_MAX - 1);
|
|
else
|
|
iCur++;
|
|
|
|
iCur %= TAB_MAX;
|
|
TabCtrl_SetCurSel(GetDlgItem(m_hwnd, IDC_SP_TABS), iCur);
|
|
OnTabChange(NULL);
|
|
}
|
|
|
|
NoKeys:
|
|
if (IsWindow(m_hwnd) && IsWindowVisible(m_hwnd))
|
|
fEaten = ::IsDialogMessage(m_hwnd, pMsg);
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (fEaten ? S_OK : S_FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::GetWindow()
|
|
//
|
|
// PURPOSE: Returns the handle to the spooler dialog window.
|
|
//
|
|
// PARAMETERS:
|
|
// <out> pHwnd - Where we return the handle.
|
|
//
|
|
// RETURN VALUE:
|
|
// E_INVALIDARG
|
|
// SP_E_UNINITIALIZED
|
|
// S_OK
|
|
//
|
|
HRESULT CSpoolerDlg::GetWindow(HWND *pHwnd)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
|
|
if (NULL == pHwnd)
|
|
return E_INVALIDARG;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
*pHwnd = m_hwnd;
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
HRESULT CSpoolerDlg::Close(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (!IsWindow(m_hwnd))
|
|
hr = SP_E_UNINITIALIZED;
|
|
else
|
|
DestroyWindow(m_hwnd);
|
|
|
|
// Unregister with Identity manager
|
|
if (m_dwIdentCookie != 0)
|
|
{
|
|
MU_UnregisterIdentityNotifier(m_dwIdentCookie);
|
|
m_dwIdentCookie = 0;
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
return (hr);
|
|
}
|
|
|
|
|
|
HRESULT CSpoolerDlg::ChangeHangupOption(BOOL fEnable, DWORD dwOption)
|
|
{
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_HANGUP), fEnable ? SW_SHOW : SW_HIDE);
|
|
::EnableWindow(GetDlgItem(m_hwnd, IDC_SP_HANGUP), fEnable);
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_HANGUP, BM_SETCHECK, dwOption, 0);
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::PostDlgProc()
|
|
//
|
|
// PURPOSE: Dialog callback for the spooler dialog proc.
|
|
//
|
|
INT_PTR CALLBACK CSpoolerDlg::SpoolerDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
CSpoolerDlg *pThis = (CSpoolerDlg *) GetWindowLongPtr(hwnd, DWLP_USER);
|
|
LRESULT lResult;
|
|
|
|
// Pass to spooler bind context
|
|
if (pThis && pThis->m_pBindCtx && pThis->m_pBindCtx->OnWindowMessage(hwnd, uMsg, wParam, lParam) == S_OK)
|
|
return (TRUE);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// Stash the this pointer so we can use it later
|
|
Assert(lParam);
|
|
SetWindowLongPtr(hwnd, DWLP_USER, lParam);
|
|
pThis = (CSpoolerDlg *) lParam;
|
|
|
|
return (BOOL) HANDLE_WM_INITDIALOG(hwnd, wParam, lParam,
|
|
pThis->OnInitDialog);
|
|
|
|
case WM_COMMAND:
|
|
if (pThis)
|
|
HANDLE_WM_COMMAND(hwnd, wParam, lParam, pThis->OnCommand);
|
|
return (TRUE);
|
|
|
|
case WM_NOTIFY:
|
|
if (pThis)
|
|
{
|
|
lResult = HANDLE_WM_NOTIFY(hwnd, wParam, lParam, pThis->OnNotify);
|
|
SetDlgMsgResult(hwnd, WM_NOTIFY, lResult);
|
|
}
|
|
return (TRUE);
|
|
|
|
case WM_DRAWITEM:
|
|
if (pThis)
|
|
HANDLE_WM_DRAWITEM(hwnd, wParam, lParam, pThis->OnDrawItem);
|
|
return (TRUE);
|
|
|
|
case WM_MEASUREITEM:
|
|
if (pThis)
|
|
HANDLE_WM_MEASUREITEM(hwnd, wParam, lParam, pThis->OnMeasureItem);
|
|
return (TRUE);
|
|
|
|
case WM_DELETEITEM:
|
|
if (pThis)
|
|
HANDLE_WM_DELETEITEM(hwnd, wParam, lParam, pThis->OnDeleteItem);
|
|
return (TRUE);
|
|
|
|
#if 0
|
|
case WM_SYSCOLORCHANGE:
|
|
case WM_SETTINGCHANGE:
|
|
if (pThis)
|
|
HANDLE_WM_SYSCOLORCHANGE(hwnd, wParam, lParam, pThis->OnSysColorChange);
|
|
return (TRUE);
|
|
#endif
|
|
|
|
case WM_CLOSE:
|
|
if (pThis)
|
|
HANDLE_WM_CLOSE(hwnd, wParam, lParam, pThis->OnClose);
|
|
return (TRUE);
|
|
|
|
case WM_DESTROY:
|
|
if (pThis)
|
|
HANDLE_WM_DESTROY(hwnd, wParam, lParam, pThis->OnDestroy);
|
|
return (TRUE);
|
|
|
|
case IMAIL_SHOWWINDOW:
|
|
::ShowWindow(hwnd, (int) lParam);
|
|
if (pThis)
|
|
pThis->ToggleStatics(lParam == SW_HIDE);
|
|
return (TRUE);
|
|
|
|
case WM_QUERYENDSESSION:
|
|
if (pThis && pThis->m_pBindCtx)
|
|
{
|
|
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pThis->m_pBindCtx->QueryEndSession(wParam, lParam));
|
|
return (TRUE);
|
|
}
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
if (pThis)
|
|
{
|
|
HANDLE_WM_CONTEXTMENU(hwnd, wParam, lParam, pThis->OnContextMenu);
|
|
return (TRUE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnInitDialog()
|
|
//
|
|
// PURPOSE: Initializes the dialog.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> hwnd - Handle of the dialog window.
|
|
// <in> hwndFocus - Handle of the control that will start with the focus.
|
|
// <in> lParam - Extra data being passed to the dialog.
|
|
//
|
|
// RETURN VALUE:
|
|
// Return TRUE to set the focus to hwndFocus
|
|
//
|
|
BOOL CSpoolerDlg::OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
|
|
{
|
|
m_hwnd = hwnd;
|
|
|
|
// Bug #38692 - Set the font correctly for Intl charsets
|
|
SetIntlFont(hwnd);
|
|
SetIntlFont(GetDlgItem(hwnd, IDC_SP_GENERAL_PROG));
|
|
SetIntlFont(GetDlgItem(hwnd, IDC_SP_SPECIFIC_PROG));
|
|
SetIntlFont(GetDlgItem(hwnd, IDC_SP_EVENTS));
|
|
SetIntlFont(GetDlgItem(hwnd, IDC_SP_ERRORS));
|
|
SetIntlFont(GetDlgItem(hwnd, IDC_SP_IDLETEXT));
|
|
|
|
// Initialize the controls on the dialog
|
|
InitializeTabs();
|
|
InitializeLists();
|
|
InitializeAnimation();
|
|
InitializeToolbar();
|
|
ToggleStatics(TRUE);
|
|
|
|
// Hide the Hangup when done deal.
|
|
// ::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_HANGUP), SW_HIDE);
|
|
|
|
// Set the hangup when done option
|
|
Button_SetCheck(GetDlgItem(m_hwnd, IDC_SP_HANGUP), DwGetOption(OPT_DIALUP_HANGUP_DONE));
|
|
|
|
// Get some information from the dialog template we'll need later
|
|
GetDlgItemText(m_hwnd, IDC_SP_OVERALL_STATUS, m_szCount, ARRAYSIZE(m_szCount));
|
|
|
|
// Initialize the rectangles that we'll need for sizing later
|
|
RECT rcSep;
|
|
GetWindowRect(GetDlgItem(hwnd, IDC_SP_SEPARATOR), &rcSep);
|
|
GetWindowRect(hwnd, &m_rcDlg);
|
|
m_cyCollapsed = rcSep.top - m_rcDlg.top;
|
|
|
|
// Load the window size from the registry
|
|
WINDOWPLACEMENT wp;
|
|
wp.length = sizeof(WINDOWPLACEMENT);
|
|
if (GetOption(OPT_SPOOLERDLGPOS, (LPVOID*) &wp, sizeof(WINDOWPLACEMENT)))
|
|
{
|
|
wp.showCmd = SW_HIDE;
|
|
SetWindowPlacement(hwnd, &wp);
|
|
ExpandCollapse(m_cyCollapsed < (DWORD) ((wp.rcNormalPosition.bottom - wp.rcNormalPosition.top)), FALSE);
|
|
}
|
|
else
|
|
{
|
|
// Center the dialog on the screen.
|
|
CenterDialog(hwnd);
|
|
ExpandCollapse(FALSE, FALSE);
|
|
}
|
|
|
|
// Set the state of the thumbtack
|
|
DWORD dwTack;
|
|
if (DwGetOption(OPT_SPOOLERTACK))
|
|
{
|
|
SendDlgItemMessage(hwnd, IDC_SP_TOOLBAR, TB_SETSTATE, IDC_SP_TACK,
|
|
MAKELONG(TBSTATE_CHECKED | TBSTATE_ENABLED, 0));
|
|
SendMessage(hwnd, WM_COMMAND, IDC_SP_TACK, 0);
|
|
}
|
|
|
|
// Disable the stop button
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SP_STOP), FALSE);
|
|
|
|
// Subclass the list box
|
|
HWND hwnderr = GetDlgItem(hwnd, IDC_SP_ERRORS);
|
|
WNDPROC proc = (WNDPROC) GetWindowLongPtr(hwnderr, GWLP_WNDPROC);
|
|
SetProp(hwnderr, c_szWndProc, proc);
|
|
SetWindowLongPtr(hwnderr, GWLP_WNDPROC, (LPARAM) ListSubClassProc);
|
|
|
|
// BUG: 44376. ATOK11 has a hidden window. If we return TRUE user will do a setfocus on US, at this point the browser
|
|
// thread is block waiting for the spooler to complete and when ATOK gets a WM_ACTIVATE they interthreadsendmsg on our blocked
|
|
// browser window with inf. timeout. So we hang at startup. Don't set focus in here at startup time.
|
|
return (FALSE);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnCommand()
|
|
//
|
|
// PURPOSE: Handle the various command messages dispatched from the dialog
|
|
//
|
|
void CSpoolerDlg::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
|
|
{
|
|
switch (id)
|
|
{
|
|
case IDCANCEL:
|
|
case IDC_SP_MINIMIZE:
|
|
if (m_fShutdown)
|
|
{
|
|
Assert(m_pBindCtx);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SP_MINIMIZE), FALSE);
|
|
m_pBindCtx->UIShutdown();
|
|
}
|
|
else
|
|
ShowWindow(SW_HIDE);
|
|
break;
|
|
|
|
case IDC_SP_STOP:
|
|
if (m_pBindCtx)
|
|
{
|
|
m_pBindCtx->Cancel();
|
|
if (GetFocus() == GetDlgItem(hwnd, IDC_SP_STOP))
|
|
SetFocus(GetDlgItem(hwnd, IDC_SP_MINIMIZE));
|
|
EnableWindow(GetDlgItem(hwnd, IDC_SP_STOP), FALSE);
|
|
}
|
|
break;
|
|
|
|
case IDC_SP_TACK:
|
|
{
|
|
UINT state = (UINT) SendDlgItemMessage(m_hwnd, IDC_SP_TOOLBAR, TB_GETSTATE,
|
|
IDC_SP_TACK, 0);
|
|
SendDlgItemMessage(m_hwnd, IDC_SP_TOOLBAR, TB_CHANGEBITMAP,
|
|
IDC_SP_TACK,
|
|
MAKELPARAM(state & TBSTATE_CHECKED ? IMAGE_TACK_IN : IMAGE_TACK_OUT, 0));
|
|
}
|
|
break;
|
|
|
|
case IDC_SP_DETAILS:
|
|
m_fSaveSize = TRUE;
|
|
ExpandCollapse(!m_fExpanded);
|
|
break;
|
|
|
|
case IDC_SP_HANGUP:
|
|
SetDwOption(OPT_DIALUP_HANGUP_DONE, BST_CHECKED == Button_GetCheck(hwndCtl), NULL, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnNotify
|
|
//
|
|
// PURPOSE: Handles notifications from the common controls on the dialog.
|
|
//
|
|
LRESULT CSpoolerDlg::OnNotify(HWND hwnd, int idFrom, LPNMHDR pnmhdr)
|
|
{
|
|
switch (pnmhdr->code)
|
|
{
|
|
case TCN_SELCHANGE:
|
|
OnTabChange(pnmhdr);
|
|
return (0);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnDrawItem()
|
|
//
|
|
// PURPOSE: Draws the link buttons
|
|
//
|
|
// PARAMETERS:
|
|
// <in> hwnd - Handle of the dialog window
|
|
// <in> lpDrawItem - Pointer to a DRAWITEMSTRUCT with the info needed to
|
|
// draw the button.
|
|
//
|
|
void CSpoolerDlg::OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT* lpDrawItem)
|
|
{
|
|
HDC hdc = lpDrawItem->hDC;
|
|
COLORREF clrText, clrBack;
|
|
RECT rcText, rcFocus;
|
|
SIZE size;
|
|
BOOL fSelected = (lpDrawItem->itemState & ODS_SELECTED) &&
|
|
(GetFocus() == lpDrawItem->hwndItem);
|
|
|
|
Assert(lpDrawItem->CtlType == ODT_LISTBOX);
|
|
if (lpDrawItem->itemID == -1)
|
|
goto exit;
|
|
|
|
// Draw the bullet first
|
|
ImageList_Draw(m_himlImages,
|
|
IMAGE_BULLET,
|
|
hdc,
|
|
BULLET_INDENT,
|
|
lpDrawItem->rcItem.top,
|
|
fSelected ? ILD_SELECTED | ILD_TRANSPARENT : ILD_TRANSPARENT);
|
|
|
|
// Set up the text rectangle
|
|
rcText = lpDrawItem->rcItem;
|
|
rcText.left += BULLET_WIDTH;
|
|
|
|
// Set up the text and background colors
|
|
clrBack = SetBkColor(hdc, GetSysColor(fSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW));
|
|
clrText = SetTextColor(hdc, GetSysColor(fSelected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
|
|
|
|
// Draw the text
|
|
FillRect(hdc, &rcText, (HBRUSH)IntToPtr((fSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW) + 1));
|
|
InflateRect(&rcText, -2, -2);
|
|
DrawText(hdc, ((LBDATA *) lpDrawItem->itemData)->pszText, -1, &rcText, DT_NOCLIP | DT_WORDBREAK);
|
|
|
|
// If we need a focus rect, do that too
|
|
if (lpDrawItem->itemState & ODS_FOCUS)
|
|
{
|
|
rcFocus = lpDrawItem->rcItem;
|
|
rcFocus.left += BULLET_WIDTH;
|
|
// InflateRect(&rcFocus, -2, -2);
|
|
DrawFocusRect(hdc, &rcFocus);
|
|
}
|
|
|
|
SetBkColor(hdc, clrBack);
|
|
SetTextColor(hdc, clrText);
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
|
|
|
|
void CSpoolerDlg::OnMeasureItem(HWND hwnd, MEASUREITEMSTRUCT *pMeasureItem)
|
|
{
|
|
LBDATA *pData = NULL;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Set the height of the item
|
|
if (NULL != (pData = (LBDATA *) ListBox_GetItemData(m_hwndErrors, pMeasureItem->itemID)))
|
|
{
|
|
pMeasureItem->itemHeight = pData->rcText.bottom;
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
}
|
|
|
|
|
|
void CSpoolerDlg::OnDeleteItem(HWND hwnd, const DELETEITEMSTRUCT * lpDeleteItem)
|
|
{
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
if (lpDeleteItem->itemData)
|
|
{
|
|
SafeMemFree(((LBDATA *)lpDeleteItem->itemData)->pszText);
|
|
MemFree((LPVOID) lpDeleteItem->itemData);
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnClose()
|
|
//
|
|
// PURPOSE: Handles the WM_CLOSE notification by sending an IDCANCEL to
|
|
// the dialog.
|
|
//
|
|
void CSpoolerDlg::OnClose(HWND hwnd)
|
|
{
|
|
SendMessage(hwnd, WM_COMMAND, IDC_SP_MINIMIZE, 0);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnDestroy()
|
|
//
|
|
// PURPOSE: Handles the WM_DESTROY notification by freeing the memory stored
|
|
// in the listview items.
|
|
//
|
|
void CSpoolerDlg::OnDestroy(HWND hwnd)
|
|
{
|
|
#ifndef _WIN64
|
|
Animate_Close(GetDlgItem(m_hwnd, IDC_SP_ANIMATE));
|
|
#endif
|
|
|
|
// Save the window placement
|
|
WINDOWPLACEMENT wp;
|
|
wp.length = sizeof(WINDOWPLACEMENT);
|
|
if (GetWindowPlacement(hwnd, &wp))
|
|
{
|
|
if (!m_fSaveSize)
|
|
{
|
|
// Load the old size out of the registry
|
|
WINDOWPLACEMENT wp2;
|
|
|
|
if (GetOption(OPT_SPOOLERDLGPOS, (LPVOID*) &wp2, sizeof(WINDOWPLACEMENT)))
|
|
{
|
|
wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + (wp2.rcNormalPosition.bottom - wp2.rcNormalPosition.top);
|
|
}
|
|
else
|
|
{
|
|
wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + m_cyCollapsed;
|
|
}
|
|
}
|
|
|
|
SetOption(OPT_SPOOLERDLGPOS, (LPVOID) &wp, sizeof(WINDOWPLACEMENT), NULL, 0);
|
|
}
|
|
|
|
DWORD dwState;
|
|
dwState = (DWORD) SendDlgItemMessage(m_hwnd, IDC_SP_TOOLBAR, TB_GETSTATE, IDC_SP_TACK, 0);
|
|
SetDwOption(OPT_SPOOLERTACK, !!(dwState & TBSTATE_CHECKED), NULL, 0);
|
|
|
|
HIMAGELIST himl;
|
|
himl = (HIMAGELIST)SendDlgItemMessage(m_hwnd, IDC_SP_TOOLBAR, TB_GETIMAGELIST, 0, 0);
|
|
if (himl)
|
|
ImageList_Destroy(himl);
|
|
|
|
HWND hwnderr = GetDlgItem(hwnd, IDC_SP_ERRORS);
|
|
WNDPROC proc = (WNDPROC)GetProp(hwnderr, c_szWndProc);
|
|
if (proc != NULL)
|
|
{
|
|
SetWindowLongPtr(hwnderr, GWLP_WNDPROC, (LPARAM)proc);
|
|
RemoveProp(hwnderr, c_szWndProc);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::InitializeTabs()
|
|
//
|
|
// PURPOSE: Initializes the tab control on the dialog.
|
|
//
|
|
// RETURN VALUE:
|
|
// TRUE if everything succeeded, FALSE otherwise.
|
|
//
|
|
BOOL CSpoolerDlg::InitializeTabs(void)
|
|
{
|
|
HWND hwndTabs = GetDlgItem(m_hwnd, IDC_SP_TABS);
|
|
TC_ITEM tci;
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
|
|
// "Tasks"
|
|
tci.mask = TCIF_TEXT;
|
|
tci.pszText = AthLoadString(idsTasks, szRes, ARRAYSIZE(szRes));
|
|
TabCtrl_InsertItem(hwndTabs, 0, &tci);
|
|
|
|
// "Errors"
|
|
tci.pszText = AthLoadString(idsErrors, szRes, ARRAYSIZE(szRes));
|
|
TabCtrl_InsertItem(hwndTabs, 1, &tci);
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::InitializeLists()
|
|
//
|
|
// PURPOSE: Initializes the list control on the dialog.
|
|
//
|
|
// RETURN VALUE:
|
|
// TRUE if everything succeeded, FALSE otherwise.
|
|
//
|
|
BOOL CSpoolerDlg::InitializeLists(void)
|
|
{
|
|
LV_COLUMN lvc;
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
RECT rcClient;
|
|
DWORD cx;
|
|
|
|
// Store the handle for the events list since we use it frequently
|
|
m_hwndEvents = GetDlgItem(m_hwnd, IDC_SP_EVENTS);
|
|
|
|
// Get the size of the client rect of the listview
|
|
GetClientRect(m_hwndEvents, &rcClient);
|
|
|
|
// "Tasks" column
|
|
lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
|
|
lvc.fmt = LVCFMT_CENTER;
|
|
lvc.cx = rcClient.right / 2;
|
|
lvc.pszText = AthLoadString(idsTasks, szRes, ARRAYSIZE(szRes));
|
|
lvc.iSubItem = 0;
|
|
ListView_InsertColumn(m_hwndEvents, 0, &lvc);
|
|
|
|
// "Status" column
|
|
cx = (rcClient.right / 2 - GetSystemMetrics(SM_CXVSCROLL)) / 2;
|
|
lvc.cx = cx;
|
|
lvc.pszText = AthLoadString(idsStatusCol, szRes, ARRAYSIZE(szRes));
|
|
lvc.iSubItem = 1;
|
|
ListView_InsertColumn(m_hwndEvents, 1, &lvc);
|
|
|
|
// "Connection" column
|
|
lvc.cx = cx;
|
|
lvc.pszText = AthLoadString(idsConnection, szRes, ARRAYSIZE(szRes));
|
|
lvc.iSubItem = 2;
|
|
ListView_InsertColumn(m_hwndEvents, 2, &lvc);
|
|
|
|
// Set the listview image list
|
|
m_himlImages = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbSpooler), 16, 0,
|
|
RGB(255, 0, 255));
|
|
|
|
if (m_himlImages)
|
|
ListView_SetImageList(m_hwndEvents, m_himlImages, LVSIL_SMALL);
|
|
|
|
// The listview looks better if we use full row select
|
|
ListView_SetExtendedListViewStyle(m_hwndEvents, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
|
|
|
|
// Initialize the Error list
|
|
m_hwndErrors = GetDlgItem(m_hwnd, IDC_SP_ERRORS);
|
|
::ShowWindow(m_hwndErrors, FALSE);
|
|
EnableWindow(m_hwndErrors, FALSE);
|
|
|
|
// Save the width of the error list
|
|
GetClientRect(m_hwndErrors, &rcClient);
|
|
m_cxErrors = rcClient.right;
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::InitializeAnimation()
|
|
//
|
|
// PURPOSE: Initializes the animation controls on the dialog.
|
|
//
|
|
// RETURN VALUE:
|
|
// TRUE if everything succeeded, FALSE otherwise.
|
|
//
|
|
BOOL CSpoolerDlg::InitializeAnimation(void)
|
|
{
|
|
#ifndef _WIN64
|
|
|
|
HWND hwndAni = GetDlgItem(m_hwnd, IDC_SP_ANIMATE);
|
|
|
|
Animate_OpenEx(hwndAni, g_hLocRes, MAKEINTRESOURCE(idanOutbox));
|
|
#endif
|
|
return (0);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::InitializeToolbar()
|
|
//
|
|
// PURPOSE: What dialog would be complete without a toolbar, eh?
|
|
//
|
|
// RETURN VALUE:
|
|
// TRUE if everything succeeded, FALSE otherwise.
|
|
//
|
|
BOOL CSpoolerDlg::InitializeToolbar(void)
|
|
{
|
|
HWND hwndTool;
|
|
RECT rcTabs;
|
|
POINT point;
|
|
|
|
HIMAGELIST himlImages = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbSpooler), 16, 0,
|
|
RGB(255, 0, 255));
|
|
|
|
GetWindowRect(GetDlgItem(m_hwnd, IDC_SP_TABS), &rcTabs);
|
|
point.x = rcTabs.right - 22;
|
|
point.y = rcTabs.bottom + 3;
|
|
ScreenToClient(m_hwnd, &point);
|
|
|
|
hwndTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
|
|
CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN |
|
|
WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | TBSTYLE_FLAT,
|
|
point.x, point.y, 22, 22,
|
|
m_hwnd, (HMENU) IDC_SP_TOOLBAR,
|
|
g_hInst, 0);
|
|
if (hwndTool)
|
|
{
|
|
#ifndef WIN16
|
|
TBBUTTON tb = { IMAGE_TACK_OUT, IDC_SP_TACK, TBSTATE_ENABLED, TBSTYLE_CHECK, {0, 0}, 0, 0 };
|
|
#else
|
|
TBBUTTON tb = { IMAGE_TACK_OUT, IDC_SP_TACK, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0 };
|
|
#endif
|
|
SendMessage(hwndTool, TB_SETIMAGELIST, 0, (LPARAM) himlImages);
|
|
SendMessage(hwndTool, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
|
SendMessage(hwndTool, TB_SETBUTTONSIZE, 0, MAKELONG(14, 14));
|
|
SendMessage(hwndTool, TB_SETBITMAPSIZE, 0, MAKELONG(14, 14));
|
|
SendMessage(hwndTool, TB_ADDBUTTONS, 1, (LPARAM) &tb);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::ExpandCollapse()
|
|
//
|
|
// PURPOSE: Takes care of showing and hiding the "details" part of the
|
|
// error dialog.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> fExpand - TRUE if we should be expanding the dialog.
|
|
//
|
|
void CSpoolerDlg::ExpandCollapse(BOOL fExpand, BOOL fSetFocus)
|
|
{
|
|
RECT rcSep;
|
|
TCHAR szBuf[64];
|
|
|
|
m_fExpanded = fExpand;
|
|
|
|
GetWindowRect(GetDlgItem(m_hwnd, IDC_SP_SEPARATOR), &rcSep);
|
|
|
|
if (!m_fExpanded)
|
|
SetWindowPos(m_hwnd, 0, 0, 0, m_rcDlg.right - m_rcDlg.left,
|
|
m_cyCollapsed, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
|
|
else
|
|
SetWindowPos(m_hwnd, 0, 0, 0, m_rcDlg.right - m_rcDlg.left,
|
|
m_rcDlg.bottom - m_rcDlg.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
|
|
|
|
// Make sure the entire dialog is visible on the screen. If not,
|
|
// then push it up
|
|
RECT rc;
|
|
RECT rcWorkArea;
|
|
GetWindowRect(m_hwnd, &rc);
|
|
SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID) &rcWorkArea, 0);
|
|
if (rc.bottom > rcWorkArea.bottom)
|
|
{
|
|
rc.top = max(0, (int) rc.top - (rc.bottom - rcWorkArea.bottom));
|
|
|
|
SetWindowPos(m_hwnd, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
|
}
|
|
|
|
AthLoadString(m_fExpanded ? idsHideDetails : idsShowDetails, szBuf,
|
|
ARRAYSIZE(szBuf));
|
|
SetDlgItemText(m_hwnd, IDC_SP_DETAILS, szBuf);
|
|
|
|
if (fExpand)
|
|
{
|
|
switch (m_iTab)
|
|
{
|
|
case TAB_TASKS:
|
|
UpdateLists(TRUE, FALSE, FALSE);
|
|
break;
|
|
case TAB_ERRORS:
|
|
UpdateLists(FALSE, TRUE, FALSE);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
UpdateLists(FALSE, FALSE, FALSE);
|
|
|
|
// Raid-34387: Spooler: Closing details with ALT-D while focus is on a task disables keyboard input
|
|
if (!fExpand && fSetFocus)
|
|
SetFocus(GetDlgItem(m_hwnd, IDC_SP_DETAILS));
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::OnTabChange()
|
|
//
|
|
// PURPOSE: Gets called in response to the user changing which tab is
|
|
// the selected tab. In response, we update which listview
|
|
// is currently visible.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> pnmhdr - Pointer to the notification information
|
|
//
|
|
void CSpoolerDlg::OnTabChange(LPNMHDR pnmhdr)
|
|
{
|
|
HWND hwndDisable1, hwndDisable2 = 0, hwndEnable;
|
|
|
|
// Find out which tab is currently active
|
|
m_iTab = TabCtrl_GetCurSel(GetDlgItem(m_hwnd, IDC_SP_TABS));
|
|
if (-1 == m_iTab)
|
|
return;
|
|
|
|
// Update which listview is visible
|
|
switch (m_iTab)
|
|
{
|
|
case TAB_TASKS:
|
|
// Hide the error listview, show the tasks list
|
|
UpdateLists(TRUE, FALSE, FALSE);
|
|
break;
|
|
|
|
case TAB_ERRORS:
|
|
// Hide the error listview, show the tasks list
|
|
UpdateLists(FALSE, TRUE, FALSE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// FUNCTION: CSpoolerDlg::UpdateLists()
|
|
//
|
|
// PURPOSE: Does the work of hiding and showing the lists when the
|
|
// tab selection changes.
|
|
//
|
|
// PARAMETERS:
|
|
// <in> fEvents - TRUE to display the events list
|
|
// <in> fErrors - TRUE to display the error list
|
|
// <in> fHistory - TRUE to display the history list
|
|
//
|
|
void CSpoolerDlg::UpdateLists(BOOL fEvents, BOOL fErrors, BOOL fHistory)
|
|
{
|
|
if (IsWindow(m_hwndEvents))
|
|
{
|
|
EnableWindow(m_hwndEvents, fEvents);
|
|
::ShowWindow(m_hwndEvents, fEvents ? SW_SHOWNA : SW_HIDE);
|
|
}
|
|
|
|
if (IsWindow(m_hwndErrors))
|
|
{
|
|
EnableWindow(m_hwndErrors, fErrors);
|
|
::ShowWindow(m_hwndErrors, fErrors ? SW_SHOWNA : SW_HIDE);
|
|
}
|
|
}
|
|
|
|
void CSpoolerDlg::ToggleStatics(BOOL fIdle)
|
|
{
|
|
m_fIdle = fIdle;
|
|
|
|
if (fIdle)
|
|
{
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_GENERAL_PROG), FALSE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_SPECIFIC_PROG), FALSE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_ANIMATE), FALSE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_IDLETEXT), TRUE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_IDLEICON), TRUE);
|
|
|
|
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_GENERAL_PROG), SW_HIDE);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_SPECIFIC_PROG), SW_HIDE);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_ANIMATE), SW_HIDE);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_IDLETEXT), SW_SHOWNA);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_IDLEICON), SW_SHOWNA);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_GENERAL_PROG), TRUE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_SPECIFIC_PROG), TRUE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_ANIMATE), TRUE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_IDLETEXT), FALSE);
|
|
EnableWindow(GetDlgItem(m_hwnd, IDC_SP_IDLEICON), FALSE);
|
|
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_GENERAL_PROG), SW_SHOWNA);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_SPECIFIC_PROG), SW_SHOWNA);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_ANIMATE), SW_SHOWNA);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_IDLETEXT), SW_HIDE);
|
|
::ShowWindow(GetDlgItem(m_hwnd, IDC_SP_IDLEICON), SW_HIDE);
|
|
}
|
|
}
|
|
|
|
|
|
void CSpoolerDlg::OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
|
|
{
|
|
POINT pt = {xPos, yPos};
|
|
RECT rcError;
|
|
LBDATA *pData = NULL;
|
|
|
|
// Check to see if the error window is visible
|
|
if (!IsWindowVisible(m_hwndErrors))
|
|
return;
|
|
|
|
// Check to see if the click was within the error window
|
|
GetWindowRect(m_hwndErrors, &rcError);
|
|
if (!PtInRect(&rcError, pt))
|
|
return;
|
|
|
|
// Do the context menu
|
|
HMENU hMenu = CreatePopupMenu();
|
|
|
|
// Add a "Copy..." item
|
|
TCHAR szRes[CCHMAX_STRINGRES];
|
|
AthLoadString(idsCopyTT, szRes, ARRAYSIZE(szRes));
|
|
|
|
// Add it to the menu
|
|
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING, ID_COPY, szRes);
|
|
|
|
// If the click is on an item in the listbox, then enable the command
|
|
ScreenToClient(m_hwndErrors, &pt);
|
|
DWORD iItem = (DWORD) SendMessage(m_hwndErrors, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y));
|
|
|
|
if (iItem != -1)
|
|
{
|
|
EnterCriticalSection(&m_cs);
|
|
pData = (LBDATA *) ListBox_GetItemData(m_hwndErrors, iItem);
|
|
LeaveCriticalSection(&m_cs);
|
|
}
|
|
|
|
if (iItem == -1 || NULL == pData || ((LBDATA*)-1) == pData)
|
|
EnableMenuItem(hMenu, ID_COPY, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
// Show the menu
|
|
DWORD id;
|
|
id = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY,
|
|
xPos, yPos, m_hwndErrors, NULL);
|
|
if (id == ID_COPY)
|
|
{
|
|
// Get the item data for the item they clicked on
|
|
LPTSTR pszDup;
|
|
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Set the height of the item
|
|
if (NULL != pData && ((LBDATA*)-1) != pData)
|
|
{
|
|
// Dupe the string. Clipboard owns the copy.
|
|
pszDup = PszDupA(pData->pszText);
|
|
|
|
// Put it on the clipboard
|
|
OpenClipboard(m_hwndErrors);
|
|
EmptyClipboard();
|
|
SetClipboardData(CF_TEXT, pszDup);
|
|
CloseClipboard();
|
|
}
|
|
|
|
LeaveCriticalSection(&m_cs);
|
|
}
|
|
|
|
if (hMenu)
|
|
DestroyMenu(hMenu);
|
|
}
|
|
|
|
HRESULT CSpoolerDlg::QuerySwitchIdentities()
|
|
{
|
|
DWORD_PTR dwResult;
|
|
|
|
if (!IsWindowEnabled(m_hwnd))
|
|
return E_PROCESS_CANCELLED_SWITCH;
|
|
|
|
if (m_pBindCtx)
|
|
{
|
|
dwResult = m_pBindCtx->QueryEndSession(0, ENDSESSION_LOGOFF);
|
|
SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, dwResult);
|
|
|
|
if (dwResult != TRUE)
|
|
return E_PROCESS_CANCELLED_SWITCH;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CSpoolerDlg::SwitchIdentities()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CSpoolerDlg::IdentityInformationChanged(DWORD dwType)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
LRESULT CALLBACK CSpoolerDlg::ListSubClassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (uMsg == WM_KEYDOWN && wParam == 'C')
|
|
{
|
|
if (0 > GetAsyncKeyState(VK_CONTROL))
|
|
{
|
|
int iSel = (int) SendMessage(hwnd, LB_GETCURSEL, 0, 0);
|
|
if (LB_ERR != iSel)
|
|
{
|
|
LBDATA *pData = NULL;
|
|
LPTSTR pszDup;
|
|
|
|
// Set the height of the item
|
|
if (NULL != (pData = (LBDATA *) ListBox_GetItemData(hwnd, iSel)))
|
|
{
|
|
// Dupe the string. Clipboard owns the copy.
|
|
pszDup = PszDupA(pData->pszText);
|
|
|
|
// Put it on the clipboard
|
|
OpenClipboard(hwnd);
|
|
EmptyClipboard();
|
|
SetClipboardData(CF_TEXT, pszDup);
|
|
CloseClipboard();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
WNDPROC wp = (WNDPROC) GetProp(hwnd, c_szWndProc);
|
|
return (CallWindowProc(wp, hwnd, uMsg, wParam, lParam));
|
|
} |