Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

433 lines
12 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: QVMISC.CPP
//
// Contents: Miscellaneous functions for QVStub including the Search dialog
// and the implementation of CStringTable.
//
// Functions:
//
// History: dd-mmm-yy History Comment
// 01-Feb-04 kraigb Created
// 12-Oct-94 davepl NTPort
//
//--------------------------------------------------------------------------
#include "qvstub.h"
#pragma hdrstop
// This is so we can tell it to stop.
extern PCQVStub g_pQV;
//+-------------------------------------------------------------------------
//
// Function: SearchThread
//
// Synopsis: Function on which we create a thread that handles the
// search dialog. This function creates the dialog then sits
// in a PeekMessage loop until the CQVStub::m_fStopSearch
// flag is TRUE, then destroys the dialog and exits. This
// way we can run a timer in the dialog to perform animation
// instead of trying to call a function every so often in the
// search code. MUCH easier to program this way.
//
// Arguments: [pv] PVOID containing application-specific data.
//
// Returns: DWORD value for ExitThread
//
// History: dd-mmm-yy History Comment
// 12-Oct-94 davepl NT Port
//
//--------------------------------------------------------------------------
DWORD APIENTRY SearchThread(PVOID pv)
{
PCQVStub pQV=(PCQVStub)pv;
DWORD dwTickLast;
DWORD dwTickCur;
TCHAR szMsg[512];
TCHAR szFormat[256]; // text from control;
TCHAR szDlgText[1024];
SHFILEINFO shfi;
if (NULL == pQV)
{
return 0;
}
pQV->m_hDlg=CreateDialogParam(pQV->m_hInst,
MAKEINTRESOURCE(IDD_SEARCH),
GetDesktopWindow(),
(DLGPROC)SearchDialogProc,
(LPARAM)pQV);
if (NULL==pQV->m_hDlg)
{
return 0;
}
//
// Set the specific filename in the dialog. If we know the type
// we can say "the <type> in <file>." Otherwise we just say
// "<file>"
// generates WM_SETTEXT to the dialog which redirects the text
// the to static message control.
//
if (SHGetFileInfo(pQV->m_szFile, 0, &shfi, sizeof(shfi), SHGFI_DISPLAYNAME) == 0)
{
shfi.szDisplayName[0] = TEXT('\0');
}
if (pQV->m_fHaveType)
{
LPVOID apsz[] = { pQV->m_szType, shfi.szDisplayName };
FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
pQV->String(IDS_TYPEINFILE),
0,
0,
szMsg,
sizeof(szMsg),
(va_list*)apsz);
}
else
{
lstrcpy(szMsg, shfi.szDisplayName);
}
GetDlgItemText(pQV->m_hDlg, IDC_FILENAME, szFormat, sizeof(szFormat));
wsprintf(szDlgText, szFormat, szMsg);
SetDlgItemText(pQV->m_hDlg, IDC_FILENAME, szDlgText);
dwTickLast = GetTickCount();
ShowWindow(pQV->m_hDlg, SW_SHOW);
SetForegroundWindow(pQV->m_hDlg);
while (!pQV->m_fStopSearch)
{
MSG msg;
// We need this to pick up clicks/keystrokes in the dialog.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (!IsDialogMessage(pQV->m_hDlg, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Check if the interval has elapsed to do an animation step.
dwTickCur = GetTickCount();
if ((dwTickCur-dwTickLast) > CTICKSANIMATION)
{
// Use WM_TIMER to step the animation.
SendMessage(pQV->m_hDlg, WM_TIMER, 0, 0L);
dwTickLast = dwTickCur;
}
}
//
// Kill the dialog if it's still around. Setting
// the handle to NULL signals SearchStop to exit.
//
DestroyWindow(pQV->m_hDlg);
pQV->m_hDlg = NULL;
return 1;
}
//+-------------------------------------------------------------------------
//
// Function: SearchDialogProc
//
// Synopsis: Dialog procedure that handles the modeless "searching" dialog to
// perform the animation while we're scanning the registry.
//
// Arguments: [hDlg] Handle to the dialog
// [iMsg] Message ID to be processed
// [wParam] wParam of the message
// [lParam] lParam of the message
//
// Returns: TRUE for WM_INITDIALOG, FALSE otherwise
//
// History: dd-mmm-yy History Comment
// 12-Oct-94 davepl NT Port
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL WINAPI SearchDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int iIcon;
static HICON rghIcon[4];
int i;
PCQVStub pQV;
RECT rc;
int cx, cy, dx, dy;
// REVIEW hard-coded icon count (4)
switch (iMsg)
{
case WM_INITDIALOG:
//Save the CQVStub pointer we were passed
SetProp(hDlg, PROP_CQVSTUBPOINTER, (HANDLE)lParam);
//Load icons for animation
iIcon=0;
for (i=IDI_SEARCH1; i <= IDI_SEARCH4; i++)
{
rghIcon[iIcon++] = LoadIcon(g_pQV->m_hInst, MAKEINTRESOURCE(i));
}
iIcon=0;
SendDlgItemMessage(hDlg, IDC_SEARCHICON, STM_SETICON, (WPARAM)rghIcon[iIcon], 0L);
//Center the dialog on the screen
GetWindowRect(hDlg, &rc);
dx = rc.right-rc.left;
dy = rc.bottom-rc.top;
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
SetWindowPos(hDlg,
NULL,
(cx-dx)/2,
(cy-dy)/2,
dx,
dy,
SWP_NOZORDER);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
pQV = (PCQVStub)GetProp(hDlg, PROP_CQVSTUBPOINTER);
pQV->SearchStop(TRUE);
break;
}
break;
case WM_TIMER:
//
// NOTE: We actually do not use a timer in this
// function: the code in SearchThread will watch
// the system tick count and send up a WM_TIMER
// message explicitly for every quarter-second of
// elapsed time. That way we always work even if
// timers are scarce.
//
iIcon = (++iIcon) % 4;
SendDlgItemMessage(hDlg,
IDC_SEARCHICON,
STM_SETICON,
(WPARAM)rghIcon[iIcon],
0L);
break;
case WM_DESTROY:
//Clean up from WM_INITDIALOG
for (i=0; i < 4; i++)
{
DestroyIcon(rghIcon[i]);
rghIcon[i]=NULL;
}
RemoveProp(hDlg, PROP_CQVSTUBPOINTER);
break;
}
return FALSE;
}
//+-------------------------------------------------------------------------
//
// Function: CStringTable Class Implementation
//
// Synopsis: Constructor stores in the app instance and clears
// the string stringtable pointers.
//
// Destructor frees the string and stringtable ptrs
// as required.
//
// Arguments: [hInst] HANDLE to the module instance from which
// we will load our strings
//
// History: dd-mmm-yy History Comment
// 12-Oct-94 davepl NT Port
//
// Notes:
//
//--------------------------------------------------------------------------
CStringTable::CStringTable(HINSTANCE hInst)
{
m_hInst = hInst;
m_pszStrings = NULL;
m_ppszTable = NULL;
return;
}
CStringTable::~CStringTable(void)
{
if (NULL!=m_pszStrings)
{
free(m_pszStrings);
}
if (NULL!=m_ppszTable)
{
free(m_ppszTable);
}
return;
}
//+-------------------------------------------------------------------------
//
// Function: CStringTable::FInit
//
// Synopsis: Initialization function for a StringTable that is prone to
// failure. If this fails then the caller is responsible for
// guaranteeing that the destructor is called quickly.
//
// Effects: Loads the strings from the string table and stores them in
// this class' array (null-terminating them in the process)
//
// Arguments: [idsMin] UINT first identifier in the stringtable
// [idsMax] UINT last identifier in the stringtable.
// [cchMax] UINT maximum string length
//
// Returns: BOOL TRUE if the function is successful,
// FALSE otherwise.
//
// History: dd-mmm-yy History Comment
// 12-Oct-94 davepl NT Port
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL CStringTable::FInit(UINT idsMin, UINT idsMax, UINT cchMax)
{
UINT i;
UINT cch;
UINT cchUsed=0;
LPTSTR psz;
m_idsMin = idsMin;
m_idsMax = idsMax;
m_cStrings = (idsMax-idsMin+1);
//
// Allocate space for the pointer table.
//
m_ppszTable=(LPTSTR *) malloc(sizeof(LPTSTR)*m_cStrings);
if (NULL==m_ppszTable)
{
return FALSE;
}
//
// Allocate enough memory for cStrings*cchMax characters.
// This will result in some unused memory, but a few K is not
// worth quibbling over.
//
// REVIEW (depends on your definition of a few, I suppose)
//
// This is horse bunk. Allocate it large.
m_pszStrings = (LPTSTR)::GlobalAlloc(GPTR, m_cStrings * 256 * sizeof(TCHAR));
if (NULL==m_pszStrings)
{
::GlobalFree((HGLOBAL)m_ppszTable);
m_ppszTable=NULL;
return FALSE;
}
//
// Load the strings: we load each string in turn into psz,
// store the string pointer into the table and increment psz
// to the next positions.
//
psz = m_pszStrings;
for (i=idsMin; i <= idsMax; i++)
{
m_ppszTable[i-idsMin] = psz;
cch = LoadString(m_hInst, i, psz, 255);
//Account for a null terminator with +1
psz += cch+1;
cchUsed += cch;
}
// Now shrink down to size actually needed.
::GlobalReAlloc((HLOCAL)m_pszStrings, (int)(psz-m_pszStrings)*SIZEOF(TCHAR), 0);
return TRUE;
}
//+-------------------------------------------------------------------------
//
// Function: CStringTable::operator[]
//
// Synopsis: Returns a pointer to the requested string in the stringtable
// or NULL if the specified string does not exist.
//
// Arguments: [uID] Index of string to retrieve pointer to
//
// Returns: LPTSTR Pointer to string, or NULL if failure
//
//
// History: dd-mmm-yy History Comment
// 12-Oct-94 davepl NT Port
//
// Notes:
//
//--------------------------------------------------------------------------
const LPTSTR CStringTable::operator[](const UINT uID) const
{
//
// Ensure the index is within (exclusive) the Min and Max string vars
if (uID < m_idsMin || uID > m_idsMax)
{
return NULL;
}
return (const LPTSTR)m_ppszTable[uID-m_idsMin];
}