Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

403 lines
9.2 KiB

/*++
Copyright (C) Microsoft Corporation, 1995 - 1999
All rights reserved.
Module Name:
spllibex.cxx
Abstract:
spllib extentions
Author:
Lazar Ivanov (LazarI) 29-Mar-2000
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "spllibex.hxx"
////////////////////////////////////////////////
//
// class CMsgBoxCounter
//
// this class counts the popups which have come up
// during it's lifetime.
//
static DWORD g_dwTlsMsgsCounterCookie = -1;
CMsgBoxCounter::CMsgBoxCounter(UINT uFlags)
: m_uCount(0),
m_uFlags(uFlags),
m_uMsgID(0)
{
if( IsInitialized() )
{
// Only one instance of CMsgBoxCounter at a time can use
// the TLS cookie
ASSERT(NULL == TlsGetValue(g_dwTlsMsgsCounterCookie));
TlsSetValue(g_dwTlsMsgsCounterCookie, reinterpret_cast<LPVOID>(this));
}
}
CMsgBoxCounter::~CMsgBoxCounter()
{
if( IsInitialized() )
{
ASSERT(this == TlsGetValue(g_dwTlsMsgsCounterCookie));
TlsSetValue(g_dwTlsMsgsCounterCookie, NULL);
}
}
BOOL CMsgBoxCounter::Initialize()
{
// allocate TLS cookies
if( !IsInitialized() )
{
g_dwTlsMsgsCounterCookie = TlsAlloc();
}
return IsInitialized();
}
BOOL CMsgBoxCounter::Uninitialize()
{
// free up the TLS cookies
if( -1 != g_dwTlsMsgsCounterCookie )
{
VERIFY(TlsFree(g_dwTlsMsgsCounterCookie));
g_dwTlsMsgsCounterCookie = -1;
}
return TRUE;
}
UINT CMsgBoxCounter::GetCount()
{
UINT uReturn = INVALID_COUNT;
if( IsInitialized() )
{
// lookup the value in the TLS
CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
uReturn = pThis->m_uCount;
}
return uReturn;
}
BOOL CMsgBoxCounter::IsInitialized()
{
// the TLS cookie should be valid to assume success
return (-1 != g_dwTlsMsgsCounterCookie);
}
void CMsgBoxCounter::LogMessage(UINT uFlags)
{
if( IsInitialized() )
{
CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
if( pThis && (pThis->m_uFlags & uFlags) )
{
// increment the message box counter
pThis->m_uCount++;
}
}
}
void CMsgBoxCounter::SetMsg(UINT uMsgID)
{
if( IsInitialized() )
{
CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
if( pThis )
{
pThis->m_uMsgID = uMsgID;
}
}
}
UINT CMsgBoxCounter::GetMsg()
{
UINT uMsgID = 0;
if( IsInitialized() )
{
CMsgBoxCounter *pThis = reinterpret_cast<CMsgBoxCounter*>(TlsGetValue(g_dwTlsMsgsCounterCookie));
if( pThis )
{
uMsgID = pThis->m_uMsgID;
}
}
return uMsgID;
}
////////////////////////////////////////////////
//
// class CPrintNotify
//
// printer notifications listener
//
CPrintNotify::CPrintNotify(
IPrinterChangeCallback *pClient,
DWORD dwCount,
const PPRINTER_NOTIFY_OPTIONS_TYPE arrNotifications,
DWORD dwFlags
):
m_bRegistered(FALSE),
m_uCookie(0),
m_dwCount(dwCount),
m_arrNotifications(arrNotifications),
m_dwFlags(dwFlags)
{
SINGLETHREADRESET(TrayUIThread)
ASSERT(pClient);
m_spClient.CopyFrom(pClient);
}
CPrintNotify::~CPrintNotify()
{
SINGLETHREAD(TrayUIThread)
// make sure we uninitialize here
Uninitialize();
}
HRESULT CPrintNotify::Initialize(LPCTSTR pszPrinter)
{
SINGLETHREAD(TrayUIThread)
ASSERT(!m_shPrinter);
ASSERT(!m_shNotify);
ASSERT(pszPrinter);
HRESULT hr = E_FAIL;
SetLastError(0);
if( NULL == m_pPrintLib.pGet() )
{
// aquire a reference to the printui lib object. this will be used
// to register/unregister notification handles in the folder cache.
TPrintLib::bGetSingleton(m_pPrintLib);
}
if( m_pPrintLib.pGet() )
{
m_strPrinter.bUpdate(pszPrinter);
DWORD dwAccess = 0; // whatever
DWORD dwErr = TPrinter::sOpenPrinter(m_strPrinter, &dwAccess, &m_shPrinter);
hr = HRESULT_FROM_WIN32(dwErr);
if( SUCCEEDED(hr) )
{
ASSERT(m_dwFlags);
PRINTER_NOTIFY_OPTIONS opt = {2, 0, m_dwCount, m_arrNotifications};
m_shNotify = FindFirstPrinterChangeNotification(m_shPrinter, m_dwFlags, 0, &opt);
// setup the HRESULT here
hr = m_shNotify ? S_OK : CreateHRFromWin32();
}
}
else
{
// build an appropriate HRESULT
hr = CreateHRFromWin32();
}
if( FAILED(hr) )
{
// if something has failed we don't want to
// keep the handles around in this case
m_shNotify = NULL;
m_shPrinter = NULL;
m_strPrinter.bUpdate(NULL);
}
return hr;
}
HRESULT CPrintNotify::Uninitialize()
{
SINGLETHREAD(TrayUIThread)
// make sure we don't listen anymore
HRESULT hr = StopListen();
// clear the handles
m_shNotify = NULL;
m_shPrinter = NULL;
m_strPrinter.bUpdate(NULL);
return hr;
}
// this is just wrappers around _NotifyRegister
HRESULT CPrintNotify::StartListen()
{
SINGLETHREAD(TrayUIThread)
ASSERT(m_shNotify);
ASSERT(m_spClient);
// register ourselves in the wait list
return _NotifyRegister(TRUE);
}
HRESULT CPrintNotify::Refresh(LPVOID lpCookie, PFN_PrinterChange pfn)
{
SINGLETHREAD(TrayUIThread)
ASSERT(m_shNotify);
ASSERT(m_spClient);
ASSERT(m_dwFlags);
HRESULT hr = S_OK;
DWORD dwChange = 0;
CAutoPtrPrinterNotify pInfo;
PRINTER_NOTIFY_OPTIONS opt = {2, PRINTER_NOTIFY_OPTIONS_REFRESH, m_dwCount, m_arrNotifications };
if( FindNextPrinterChangeNotification(m_shNotify, &dwChange, &opt, pInfo.GetPPV()) )
{
// we hope the client callback will process this call quickly as there shouldn't
// be any delays here if we don't want to loose notifications.
// we don't really care what the retirn value is here.
if( pfn )
{
pfn(lpCookie, m_uCookie, dwChange, pInfo);
}
else
{
m_spClient->PrinterChange(m_uCookie, dwChange, pInfo);
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}
// this is just wrappers around _NotifyRegister
HRESULT CPrintNotify::StopListen()
{
SINGLETHREAD(TrayUIThread)
// unregister ourselves from the wait list
return _NotifyRegister(FALSE);
}
HRESULT CPrintNotify::SetCookie(ULONG_PTR uCookie)
{
SINGLETHREAD(TrayUIThread)
m_uCookie = uCookie;
return S_OK;
}
LPCTSTR CPrintNotify::GetPrinter() const
{
// !!MT NOTES!!
// this function can be invoked only from the bkgnd threads,
// but it never touches the object state.
return (0 == m_strPrinter.uLen() ? NULL : m_strPrinter);
}
HANDLE CPrintNotify::GetPrinterHandle() const
{
SINGLETHREAD(TrayUIThread)
return m_shPrinter;
}
HRESULT CPrintNotify::_NotifyRegister(BOOL bRegister)
{
SINGLETHREAD(TrayUIThread)
HRESULT hr = E_FAIL;
ASSERT(m_pPrintLib.pGet());
if( bRegister )
{
// register request
hr = (m_bRegistered ? S_OK : HRESULT_FROM_WIN32(m_pPrintLib->pNotify()->sRegister(this)));
m_bRegistered = SUCCEEDED(hr) ? TRUE : m_bRegistered;
}
else
{
// unregister request
hr = (!m_bRegistered ? S_OK : HRESULT_FROM_WIN32(m_pPrintLib->pNotify()->sUnregister(this)));
m_bRegistered = SUCCEEDED(hr) ? FALSE : m_bRegistered;
}
return hr;
}
HANDLE CPrintNotify::hEvent() const
{
// !!MT NOTES!!
// this function can be invoked only from the bkgnd threads,
// but it never touches the object state.
ASSERT(m_shNotify);
return m_shNotify;
}
void CPrintNotify::vProcessNotifyWork(TNotify *pNotify)
{
// !!MT NOTES!!
// this function can be invoked only from the bkgnd threads,
// but it never touches the object state.
ASSERT(m_shNotify);
ASSERT(m_spClient);
DWORD dwChange = 0;
CAutoPtrPrinterNotify pInfo;
PRINTER_NOTIFY_OPTIONS opt = {2, 0, m_dwCount, m_arrNotifications };
if( FindNextPrinterChangeNotification(m_shNotify, &dwChange, &opt, pInfo.GetPPV()) )
{
// we hope the client callback will process this call quickly as there shouldn't
// be any delays here if we don't want to loose notifications.
// we don't really care what the retirn value is here.
m_spClient->PrinterChange(m_uCookie, dwChange, pInfo);
}
}
////////////////////////////////////////////////
// class CMultilineEditBug
//
LRESULT CMultilineEditBug::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HWND hDlg = GetParent(hwnd);
if( hDlg && GetParent(hDlg) )
{
hDlg = GetParent(hDlg);
}
if( hDlg && WM_KEYDOWN == uMsg && VK_RETURN == wParam && GetKeyState(VK_CONTROL) >= 0 )
{
LRESULT lr = SendMessage(hDlg, DM_GETDEFID, 0, 0);
if( lr && LOWORD(lr) && DC_HASDEFID == HIWORD(lr) )
{
HWND hwndButton = GetDlgItem(hDlg, LOWORD(lr));
PostMessage(hDlg, WM_COMMAND, MAKEWPARAM(LOWORD(lr), BN_CLICKED), (LPARAM)hwndButton);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}