windows-nt/Source/XPSP1/NT/sdktools/restools/rltools/common/wincomon.c
2020-09-26 16:20:57 +08:00

463 lines
13 KiB
C

// Not sure which of these includes are/will be needed - t-gregti
#include <windows.h>
//#include <port1632.h>
#include <commdlg.h>
// CRT includes
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <io.h>
#include <time.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <ctype.h>
// RL TOOLS SET includes
#include "windefs.h"
#include "restok.h"
#include "wincomon.h"
int LoadStrIntoAnsiBuf(
HINSTANCE hinst,
UINT idResource,
LPSTR lpszBuffer,
int cbBuffer )
{
int rc;
#ifdef RLRES32
WCHAR tszTmpBuf[256];
rc = LoadString( hinst, idResource, tszTmpBuf, TCHARSIN( sizeof( tszTmpBuf)));
_WCSTOMBS( lpszBuffer,
tszTmpBuf,
cbBuffer,
lstrlen( tszTmpBuf ) + 1 );
#else
rc = LoadString( hinst, idResource, lpszBuffer, cbBuffer );
#endif
return( rc);
}
/**
* Function: GetFileNameFromBrowse.
* Uses the commdlg.dll GetOpenFileName function to prompt the user
* file name.
*
* Arguments:
* hDlg, Owner for browse dialog.
* pszFileName, // buffer to insert file name
* cbFilePath, // Max length of file path buffer.
* szTitle, // Working directory
* szFilter, // filters string.
* szDefExt // Default extension to file name
*
* Returns:
* TRUE, pszFileName contains file name.
* FALSE, GetFileName aborted.
*
* History:
* 9/91 Copied from NotePad sources. TerryRu.
**/
BOOL GetFileNameFromBrowse(HWND hDlg,
PSTR pszFileName,
UINT cbFilePath,
PSTR szTitle,
PSTR szFilter,
PSTR szDefExt)
{
OPENFILENAMEA ofn; // Structure used to init dialog.
CHAR szBrowserDir[128]; // Directory to start browsing from.
szBrowserDir[0] = '\0'; // By default use CWD.
// initalize ofn to NULLS
memset( (void *)&ofn, 0, sizeof( OPENFILENAMEA ) );
/* fill in non-variant fields of OPENFILENAMEA struct. */
ofn.lStructSize = sizeof(OPENFILENAMEA);
ofn.lpstrCustomFilter = szCustFilterSpec;
ofn.nMaxCustFilter = MAXCUSTFILTER;
ofn.nFilterIndex = 1;
ofn.lpstrFile = pszFileName;
ofn.nMaxFile = MAXFILENAME;
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = MAXFILENAME;
ofn.lpTemplateName = NULL;
ofn.lpfnHook = NULL;
// Setup info for comm dialog.
ofn.hwndOwner = hDlg;
ofn.lpstrInitialDir = szBrowserDir;
ofn.Flags = OFN_HIDEREADONLY;
ofn.lpstrDefExt = szDefExt;
ofn.lpstrFileTitle = szFileTitle;
ofn.lpstrTitle = szTitle;
ofn.lpstrFilter = szFilter;
// Get a filename from the dialog.
return GetOpenFileNameA(&ofn);
}
#define MAX_STATUS_FIELDS 5
#define MAXBUFFERSIZE 80
/****************************************************************************
*Procedure: StatusWndProc
*
*Inputs:
*
*Returns:
* depends on message
*
*History:
* 7/92 - created - t-gregti
*
*Comments:
* More general than strictly neccesary for the RL tools, but
* it makes adding new fields to the status line really easy.
* For WM_FMTSTATLINE the lParam should be a string with length/type pairs
* much like a printf format, e.g. "10s5i10s20i".
* For WM_UPDSTATLINE the wParam contains the field to change and the lParam
* contains a pointer to a string or int to display.
*
*****************************************************************************/
INT_PTR APIENTRY StatusWndProc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hDC;
static HFONT hFontCourier;
static UINT cFields = 0;
static UINT aiSize[MAX_STATUS_FIELDS];
static TCHAR aszStatusStrings[MAX_STATUS_FIELDS][MAXBUFFERSIZE];
static BOOL abIntegers[MAX_STATUS_FIELDS];
switch( wMsg )
{
case WM_CREATE:
{
LOGFONT lf;
memset( (void *)&lf, 0, sizeof(LOGFONT) );
// Intialize font info
lf.lfWeight = 400; //Normal
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = PROOF_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lf.lfHeight = 14;
lf.lfWidth = 0;
lf.lfUnderline = 0;
lstrcpy ( lf.lfFaceName, TEXT("Courier"));
// Get a handle to the courier font
hFontCourier = CreateFontIndirect( (void *)& lf );
break;
}
case WM_DESTROY:
DeleteObject((HGDIOBJ)hFontCourier);
break;
case WM_FMTSTATLINE:
{
TCHAR *psz;
#ifdef RLRES32
CHAR sz[MAXBUFFERSIZE];
#endif
cFields = 0;
for (psz = (LPTSTR)lParam; *psz; psz++)
{
cFields++;
#ifdef RLRES32
_WCSTOMBS( sz,
psz,
ACHARSIN( sizeof( sz)),
lstrlen( psz) + 1);
aiSize[cFields-1] = atoi(sz);
#else
aiSize[cFields-1] = atoi(psz);
#endif
while(_istdigit(*psz))
{
psz++;
}
switch(*psz)
{
case 'i':
abIntegers[cFields-1] = TRUE;
break;
case 's':
abIntegers[cFields-1] = FALSE;
break;
default:
cFields = 0;
return(FALSE);
}
}
return(TRUE);
}
case WM_UPDSTATLINE:
// intialize status line info, and force it to be painted
if (wParam > cFields)
{
return(FALSE);
}
if (abIntegers[wParam]) // Is it for an integer field?
{
#ifdef RLRES32
char sz[MAXBUFFERSIZE] = "";
_itoa((INT)lParam, sz, 10);
_MBSTOWCS( aszStatusStrings[ wParam],
sz,
WCHARSIN( sizeof( sz)),
ACHARSIN( lstrlenA( sz)+1));
#else
_itoa(lParam, aszStatusStrings[wParam], 10);
#endif
}
else
{
#ifdef RLWIN32
CopyMemory( aszStatusStrings[ wParam],
(LPTSTR)lParam,
min( MAXBUFFERSIZE, MEMSIZE( lstrlen( (LPTSTR)lParam) + 1)));
aszStatusStrings[ wParam][ MAXBUFFERSIZE - 1] = TEXT('\0');
#else
_fstrncpy(aszStatusStrings[wParam], (LPTSTR)lParam, MAXBUFFERSIZE-1);
#endif
aszStatusStrings[wParam][MAXBUFFERSIZE-1] = 0;
}
InvalidateRect( hWnd, NULL, TRUE );
break;
case WM_PAINT:
{
RECT r;
HFONT hOldFont;
HBRUSH hbrOld, hbrFace, hbrHilite, hbrShadow;
TEXTMETRIC tm;
int iWidth, iHeight;
UINT i;
/* Obtain a handle to the device context */
memset((void *)&ps, 0x00, sizeof(PAINTSTRUCT));
hDC = BeginPaint(hWnd, &ps);
GetTextMetrics(hDC, &tm);
GetClientRect( hWnd, &r );
iWidth = r.right - r.left;
iHeight = r.bottom - r.top;
// Create the brushes for the 3D effect
hbrFace = CreateSolidBrush(RGB(0xC0, 0xC0, 0xC0));
hbrHilite = CreateSolidBrush(RGB(0xFF, 0xFF, 0xFF));
hbrShadow = CreateSolidBrush(RGB(0x80, 0x80, 0x80));
// Paint outer 3D effect for raised slab
hbrOld = (HBRUSH)SelectObject(hDC, (HGDIOBJ)hbrHilite);
PatBlt(hDC, r.left, r.top, iWidth, 1, PATCOPY);
PatBlt(hDC, r.left, r.top+1, 1, iHeight-2, PATCOPY);
SelectObject(hDC, (HGDIOBJ)hbrShadow);
PatBlt(hDC, r.left, r.bottom-1, iWidth, 1, PATCOPY);
PatBlt(hDC, r.right-1, r.top+1, 1, iHeight-2, PATCOPY);
// Paint surface of slab
r.left += 1;
r.top += 1;
r.right -= 1;
r.bottom -= 1;
iWidth -= 2;
iHeight -= 2;
SelectObject(hDC, (HGDIOBJ)hbrFace);
PatBlt(hDC, r.left, r.top, iWidth, iHeight, PATCOPY);
// Get Courier font
hOldFont = (HFONT)SelectObject( hDC, (HGDIOBJ)hFontCourier );
SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
// Paint inner 3D effect for tray carved into slab and write text
r.left += 9;
r.right -= 9;
r.top += 3;
r.bottom -= 3;
iHeight = r.bottom - r.top;
for (i = 0; i < cFields; i++)
{
iWidth = tm.tmMaxCharWidth * aiSize[i];
r.right = r.left + iWidth - 2;
SelectObject(hDC, (HGDIOBJ)hbrShadow);
PatBlt(hDC, r.left-1, r.top-1, iWidth, 1, PATCOPY);
PatBlt(hDC, r.left-1, r.top, 1, iHeight-2, PATCOPY);
SelectObject(hDC, (HGDIOBJ)hbrHilite);
PatBlt(hDC, r.left-1, r.bottom, iWidth, 1, PATCOPY);
PatBlt(hDC, r.left + iWidth-1, r.top, 1, iHeight-2, PATCOPY);
DrawText(hDC, aszStatusStrings[i],
STRINGSIZE( lstrlen( aszStatusStrings[i])),
&r, DT_SINGLELINE);
r.left += iWidth + 8;
}
// Put old brush back and delete the rest
SelectObject(hDC, (HGDIOBJ)hbrOld);
DeleteObject((HGDIOBJ)hbrFace);
DeleteObject((HGDIOBJ)hbrHilite);
DeleteObject((HGDIOBJ)hbrShadow);
SelectObject(hDC,(HGDIOBJ)hOldFont);
EndPaint ( hWnd, (CONST PAINTSTRUCT *)&ps );
break; /* End of WM_PAINT */
}
}
return( DefWindowProc( hWnd, wMsg, wParam, lParam ));
}
/**
* Function: cwCenter
* Centers Dialog boxes in main window.
*
**/
void cwCenter( HWND hWnd, int top )
{
POINT pt;
RECT swp;
RECT rParent;
int iwidth;
int iheight;
GetWindowRect(hWnd, &swp);
GetWindowRect(hMainWnd, &rParent);
/* calculate the height and width for MoveWindow */
iwidth = swp.right - swp.left;
iheight = swp.bottom - swp.top;
/* find the center point */
pt.x = (rParent.right - rParent.left) / 2;
pt.y = (rParent.bottom - rParent.top) / 2;
/* calculate the new x, y starting point */
pt.x = pt.x - (iwidth / 2);
pt.y = pt.y - (iheight / 2);
ClientToScreen(hMainWnd,&pt);
/* top will adjust the window position, up or down */
if(top)
pt.y = pt.y + top;
if (pt.x < 0)
pt.x=0;
else
if (pt.x + iwidth > GetSystemMetrics(SM_CXSCREEN))
pt.x = GetSystemMetrics(SM_CXSCREEN)-iwidth;
/* move the window */
MoveWindow(hWnd, pt.x, pt.y, iwidth, iheight, FALSE);
}
/**
* Function: szFilterSpecFromSz1Sz2
* Returns a filter spec with the format "%s\0%s\0\0" suitable for
* use with the Windows 3.1 standard load dialog box.
*
* Arguments:
* sz, destination buffer
* sz1, first string
* sz2, second string
*
* Returns:
* result in sz
*
* Error Codes:
* none
*
* Comments:
* Performs no bounds checking. sz is assumed to be large enough to
* accomidate the filter string.
*
* History:
* 2/92, Implemented SteveBl
*/
void szFilterSpecFromSz1Sz2(CHAR *sz,CHAR *sz1, CHAR *sz2)
{
int i1 = 0;
int i2 = 0;
while (sz[i1++] = sz1[i2++]);
i2 = 0;
while (sz[i1++] = sz2[i2++]);
sz[i1]=0;
}
/**
* Function: CatSzFilterSpecs
* Concatonates two szFilterSpecs (double null terminated strings)
* and returns a buffer with the result.
*
* Arguments:
* sz, destination buffer
* sz1, first Filter Spec
* sz2, second Filter Spec
*
* Returns:
* result in sz
*
* Error Codes:
* none
*
* Comments:
* performs no bounds checking
*
* History:
* 3/92, initial implementation -- SteveBl
*/
void CatSzFilterSpecs(CHAR *sz,CHAR *sz1,CHAR *sz2)
{
int i1 = 0;
int i2 = 0;
while (sz1[i2] || sz1[i2+1]) // looking for double byte
{
sz[i1++]=sz1[i2++];
}
sz[i1++] = '\0';
i2 = 0;
while (sz2[i2] || sz2[i2+1])
{
sz[i1++]=sz2[i2++];
}
sz[i1++] = '\0';
sz[i1++] = '\0';
}