mirror of https://github.com/lianthony/NT4.0
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.
364 lines
10 KiB
364 lines
10 KiB
/******************************* MODULE HEADER *******************************
|
|
* utils.c
|
|
* Functions to interface to the help system.
|
|
*
|
|
*
|
|
* Copyright (C) 1993 Microsoft Corporation.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "rasuipch.h"
|
|
|
|
/*
|
|
* Some stuff associated with help.
|
|
*/
|
|
|
|
static WCHAR wcHelpFNM[] = L"\\hprasdui.hlp";
|
|
|
|
WCHAR *pwszHelpFile = NULL; /* Filled in when needed */
|
|
|
|
static int cHelpInit = 0; /* Only do it once */
|
|
|
|
static HHOOK hhookGetMsg;
|
|
|
|
|
|
|
|
/*
|
|
* Local function prototypes.
|
|
*/
|
|
|
|
|
|
LRESULT CALLBACK GetMsgProc( int, WPARAM, LPARAM );
|
|
|
|
|
|
/************************* Function Header *********************************
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Duplicate a Unicode string
|
|
*
|
|
* Arguments:
|
|
*
|
|
* unicodeString - Pointer to the input Unicode string
|
|
* hheap - Handle to a heap from which to allocate memory
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Pointer to the resulting Unicode string
|
|
* NULL if there is an error
|
|
****************************************************************************/
|
|
|
|
|
|
PWSTR
|
|
GetStringFromUnicode(
|
|
PWSTR unicodeString,
|
|
HANDLE hHeap
|
|
)
|
|
|
|
|
|
{
|
|
PWSTR pwstr;
|
|
INT length;
|
|
|
|
ASSERTRASDD((unicodeString != NULL), "NULL Source in GetStringFromUnicode");
|
|
length = wcslen(unicodeString) + 1;
|
|
|
|
if ((pwstr = HeapAlloc(hHeap, 0, length * sizeof(WCHAR))) != NULL) {
|
|
wcscpy(pwstr, unicodeString);
|
|
} else {
|
|
RASDERRMSG("HEAPALLOC");
|
|
}
|
|
|
|
return pwstr;
|
|
}
|
|
|
|
|
|
/************************* Function Header *********************************
|
|
* vHelpInit
|
|
* Called to initialise the help operations. Not much to do, but er
|
|
* do keep track of how many times we are called, and only do the
|
|
* initialisation once, and hence make sure we free it only once.
|
|
*
|
|
* RETURNS:
|
|
* Nothing, failure of help is benign.
|
|
*
|
|
* HISTORY:
|
|
* 13:45 on Wed 24 Feb 1993 -by- Lindsay Harris [lindsayh]
|
|
* Starting.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void
|
|
vHelpInit(
|
|
HANDLE hPrinter,
|
|
BOOL bInitHelpFileOnly
|
|
)
|
|
{
|
|
|
|
DWORD dwSize; /* See how much storage is needed for file name */
|
|
DWORD cb;
|
|
PDRIVER_INFO_3 pDriverInfo = NULL;
|
|
PWSTR pDriverDirectory; /* Comes from the spooler */
|
|
|
|
if( pwszHelpFile == NULL )
|
|
{
|
|
// Attempt to get help file name using the new DRIVER_INFO_3
|
|
|
|
if (! GetPrinterDriver(hPrinter, NULL, 3, NULL, 0, &cb) &&
|
|
GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
|
|
(pDriverInfo = HeapAlloc( hGlobalHeap, 0, cb)) &&
|
|
GetPrinterDriver(hPrinter, NULL, 3, (PBYTE) pDriverInfo, cb, &cb) &&
|
|
pDriverInfo->pHelpFile != NULL)
|
|
{
|
|
pwszHelpFile = GetStringFromUnicode(pDriverInfo->pHelpFile, hGlobalHeap);
|
|
}
|
|
|
|
if (pDriverInfo != NULL) {
|
|
HeapFree( hGlobalHeap, 0, pDriverInfo );
|
|
}
|
|
|
|
|
|
// If DRIVER_INFO_3 isn't supported, get help file name
|
|
// using the same old method as before
|
|
if (pwszHelpFile == NULL)
|
|
{
|
|
pDriverDirectory = GetDriverDirectory( hGlobalHeap, hPrinter );
|
|
|
|
if( pDriverDirectory )
|
|
{
|
|
|
|
/* Grab some memory & fill it in */
|
|
|
|
dwSize = (1 + wcslen( wcHelpFNM ) + wcslen( pDriverDirectory ) )
|
|
* sizeof( WCHAR );
|
|
|
|
if( pwszHelpFile = (WCHAR *)HeapAlloc( hGlobalHeap, 0, dwSize ) )
|
|
{
|
|
wcscpy( pwszHelpFile, pDriverDirectory );
|
|
|
|
wcscat( pwszHelpFile, wcHelpFNM ); /* The name */
|
|
}
|
|
else
|
|
{
|
|
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
return ; /* Whatever it is, this should not happen */
|
|
}
|
|
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
|
|
}
|
|
|
|
}
|
|
/*
|
|
* All we need to do (and only the first time!) is put a hook function
|
|
* onto the message queue so that we can intercept the <F1> key and
|
|
* transform it into a mouse click on the "Help" button. Then the
|
|
* normal windowing code will display the help contents.This should be
|
|
* done only for old type of help, like softfont in PrinterProperties.
|
|
*/
|
|
if( cHelpInit == 0 && !bInitHelpFileOnly )
|
|
{
|
|
/* First time only */
|
|
hhookGetMsg = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc, hModule,
|
|
GetCurrentThreadId() );
|
|
}
|
|
++cHelpInit; /* Only do it once */
|
|
|
|
|
|
return ;
|
|
}
|
|
|
|
|
|
/************************** Function Header *******************************
|
|
* vHelpDone
|
|
* Called to discombobulate help.
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
* HISTORY:
|
|
* 13:09 on Mon 01 Mar 1993 -by- Lindsay Harris [lindsayh]
|
|
* Free help file name when done.
|
|
*
|
|
* 13:52 on Wed 24 Feb 1993 -by- Lindsay Harris [lindsayh]
|
|
* First version.
|
|
*
|
|
**************************************************************************/
|
|
|
|
void
|
|
vHelpDone(
|
|
HWND hWnd, /* Required to allow us to clean up nicely */
|
|
BOOL bInitHelpFileOnly
|
|
)
|
|
{
|
|
|
|
--cHelpInit;
|
|
|
|
if( cHelpInit == 0 )
|
|
{
|
|
if (!bInitHelpFileOnly)
|
|
{
|
|
/* Does the right thing for help to go away, if shown */
|
|
vShowHelp( hWnd, HELP_QUIT, 0L, NULL );
|
|
UnhookWindowsHookEx( hhookGetMsg );
|
|
}
|
|
if( pwszHelpFile )
|
|
{
|
|
HeapFree( hGlobalHeap, 0, (LPSTR)pwszHelpFile );
|
|
pwszHelpFile = NULL;
|
|
}
|
|
}
|
|
else if( cHelpInit < 0 )
|
|
cHelpInit = 0; /* Should never happen, but.... */
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
/************************** Function Header *******************************
|
|
* vShowHelp
|
|
* Front end to the help facility, basically providing a pop-up if
|
|
* the help file is not available.
|
|
*
|
|
* RETURNS:
|
|
* Nothing
|
|
*
|
|
* HISTORY:
|
|
* 13:09 on Mon 01 Mar 1993 -by- Lindsay Harris [lindsayh]
|
|
* Generate the help file name when needed.
|
|
*
|
|
* 16:29 on Mon 22 Feb 1993 -by- Lindsay Harris [lindsayh]
|
|
* First rasddui incarnation, borrowed from printman (AndrewBe).
|
|
*
|
|
**************************************************************************/
|
|
|
|
void
|
|
vShowHelp( hWnd, iType, dwData, hPrinter)
|
|
HWND hWnd; /* Window of interest */
|
|
UINT iType; /* Type of help, param #3 to WinHelp */
|
|
DWORD dwData; /* Additional data for WinHelp, sometimes optional */
|
|
HANDLE hPrinter;
|
|
{
|
|
|
|
/*
|
|
* Quite easy - simply call the WinHelp function with the parameters
|
|
* supplied to us. If this fails, then put up a stock dialog box.
|
|
* BUT the first time we figure out what the file name is. We know
|
|
* the actual name, but we don't know where it is located, so we
|
|
* need to call the spooler for that information.
|
|
*/
|
|
|
|
DWORD dwSize; /* See how much storage is needed for file name */
|
|
|
|
PWSTR pDriverDirectory; /* Comes from the spooler */
|
|
|
|
|
|
if( pwszHelpFile == NULL )
|
|
{
|
|
if( iType == HELP_QUIT )
|
|
return; /* We are going away anyway! */
|
|
|
|
pDriverDirectory = GetDriverDirectory( hGlobalHeap, hPrinter );
|
|
|
|
if( pDriverDirectory )
|
|
{
|
|
|
|
/* Grab some memory & fill it in */
|
|
|
|
dwSize = (1 + wcslen( wcHelpFNM ) + wcslen( pDriverDirectory ) )
|
|
* sizeof( WCHAR );
|
|
|
|
if( pwszHelpFile = (WCHAR *)HeapAlloc( hGlobalHeap, 0, dwSize ) )
|
|
{
|
|
wcscpy( pwszHelpFile, pDriverDirectory );
|
|
|
|
wcscat( pwszHelpFile, wcHelpFNM ); /* The name */
|
|
}
|
|
else
|
|
return;
|
|
|
|
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
|
|
}
|
|
else
|
|
{
|
|
HeapFree( hGlobalHeap, 0, (LPSTR)pDriverDirectory );
|
|
|
|
return; /* Whatever it is, this should not happen */
|
|
}
|
|
|
|
}
|
|
|
|
if( !WinHelp( hWnd, pwszHelpFile, iType, dwData ) )
|
|
{
|
|
/* Well, help failed, so at least tell the user! */
|
|
|
|
DialogBox( hModule, MAKEINTRESOURCE( ERR_NO_HELP ), hWnd,
|
|
(DLGPROC)GenDlgProc );
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/***************************** Function Header ****************************
|
|
* GetMsgProc
|
|
* Function to hook F1 key presses and turn them into standard
|
|
* help type messages.
|
|
*
|
|
* RETURNS:
|
|
* 0 for an F1 key press, else whatever comes back from CallNextHookEx()
|
|
*
|
|
* HISTORY:
|
|
* 13:26 on Wed 24 Feb 1993 -by- Lindsay Harris [lindsayh]
|
|
* First incarnation here, following a life in printman.c (AndrewBe)
|
|
*
|
|
**************************************************************************/
|
|
|
|
LRESULT CALLBACK
|
|
GetMsgProc( iCode, wParam, lParam )
|
|
int iCode;
|
|
WPARAM wParam;
|
|
LPARAM lParam;
|
|
{
|
|
|
|
/*
|
|
* This is the callback routine which hooks F1 keypresses.
|
|
*
|
|
* Any such message will be repackaged as a WM_COMMAND/IDD_HELP message
|
|
* and sent to the top window, which may be the frame window
|
|
* or a dialog box.
|
|
*
|
|
* See the Win32 API programming reference for a description of how this
|
|
* routine works.
|
|
*
|
|
*/
|
|
|
|
PMSG pMsg = (PMSG)lParam;
|
|
|
|
if( iCode < 0 )
|
|
return CallNextHookEx( hhookGetMsg, iCode, wParam, lParam );
|
|
|
|
if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1 )
|
|
{
|
|
|
|
/* Go looking for the real parent - why? */
|
|
HWND hwndParent;
|
|
BOOL bRet;
|
|
|
|
|
|
hwndParent = pMsg->hwnd;
|
|
|
|
while( GetWindowLong( hwndParent, GWL_STYLE ) & WS_CHILD )
|
|
hwndParent = (HWND)GetWindowLong( hwndParent, GWL_HWNDPARENT );
|
|
|
|
|
|
/* Our window procs all use the same format for help operations. */
|
|
bRet = PostMessage( hwndParent, WM_COMMAND, IDD_HELP, 0L );
|
|
}
|
|
|
|
return 0;
|
|
}
|