|
|
// =================================================================================
// Common functions
// Written by: Steven J. Bailey on 1/21/96
// =================================================================================
#include "pch.hxx"
#include <shlwapi.h>
#include "xpcomm.h"
#include "strconst.h"
#include "error.h"
#include "deterr.h"
#include "progress.h"
#include "imaildlg.h"
#include "imnact.h"
#include "demand.h"
// =================================================================================
// Prototypes
// =================================================================================
INT_PTR CALLBACK DetailedErrorDlgProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL DetailedErrorDlgProc_OnInitDialog (HWND hwndDlg, HWND hwndFocus, LPARAM lParam); void DetailedErrorDlgProc_OnCommand (HWND hwndDlg, int id, HWND hwndCtl, UINT codeNotify); void DetailedErrorDlgProc_OnOk (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode); void DetailedErrorDlgProc_OnCancel (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode); void DetailedErrorDlgProc_OnDetails (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode);
// =================================================================================
// Defines
// =================================================================================
#define IDT_PROGRESS_DELAY WM_USER + 1
// =================================================================================
// SzStrAlloc
// =================================================================================
LPTSTR SzStrAlloc (ULONG cch) { LPTSTR psz = NULL;
if (!MemAlloc ((LPVOID *)&psz, (cch + 1) * sizeof (TCHAR))) return NULL; return psz; }
// ------------------------------------------------------------------------------------
// InetMailErrorDlgProc (no longer part of CInetMail)
// ------------------------------------------------------------------------------------
INT_PTR CALLBACK InetMailErrorDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals
LPINETMAILERROR pError; static RECT s_rcDialog; static BOOL s_fDetails=FALSE; RECT rcDetails, rcDlg; DWORD cyDetails; TCHAR szRes[255]; TCHAR szMsg[255 + 50]; HWND hwndDetails; // Handle Message
switch (uMsg) { case WM_INITDIALOG: // Get the pointer
pError = (LPINETMAILERROR)lParam; if (!pError) { Assert (FALSE); EndDialog(hwnd, IDCANCEL); return 1; }
// Center
CenterDialog (hwnd);
// Set Error message
Assert(pError->pszMessage); if (pError->pszMessage) SetDlgItemText(hwnd, idsInetMailError, pError->pszMessage);
// Get whnd of details
hwndDetails = GetDlgItem(hwnd, ideInetMailDetails);
// Set Details
if (!FIsStringEmpty(pError->pszDetails)) { SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)pError->pszDetails); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)g_szCRLF); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)g_szCRLF); }
// Configuration
if (AthLoadString(idsDetails_Config, szRes, sizeof(szRes)/sizeof(TCHAR))) { SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szRes); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)g_szCRLF); }
// Account:
if (!FIsStringEmpty(pError->pszAccount)) { TCHAR szAccount[255 + CCHMAX_ACCOUNT_NAME]; if (AthLoadString(idsDetail_Account, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szAccount, ARRAYSIZE(szAccount), " %s %s\r\n", szRes, pError->pszAccount); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szAccount); } }
// Server:
if (!FIsStringEmpty(pError->pszServer)) { TCHAR szServer[255 + CCHMAX_SERVER_NAME]; if (AthLoadString(idsDetail_Server, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szServer, ARRAYSIZE(szServer), " %s %s\r\n", szRes, pError->pszServer); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szServer); } }
// User Name:
if (!FIsStringEmpty(pError->pszUserName)) { TCHAR szUserName[255 + CCHMAX_USERNAME]; if (AthLoadString(idsDetail_UserName, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szUserName, ARRAYSIZE(szUserName), " %s %s\r\n", szRes, pError->pszUserName); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szUserName); } }
// Protocol:
if (!FIsStringEmpty(pError->pszProtocol)) { TCHAR szProtocol[255 + 10]; if (AthLoadString(idsDetail_Protocol, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szProtocol, ARRAYSIZE(szProtocol), " %s %s\r\n", szRes, pError->pszProtocol); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szProtocol); } }
// Port:
if (AthLoadString(idsDetail_Port, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %d\r\n", szRes, pError->dwPort); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg); } // Secure:
if (AthLoadString(idsDetail_Secure, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %d\r\n", szRes, pError->fSecure); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg); }
// Error Number:
if (pError->dwErrorNumber) { if (AthLoadString(idsDetail_ErrorNumber, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %d\r\n", szRes, pError->dwErrorNumber); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg); } }
// HRESULT:
if (pError->hrError) { if (AthLoadString(idsDetail_HRESULT, szRes, sizeof(szRes)/sizeof(TCHAR))) { wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %08x\r\n", szRes, pError->hrError); SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg); } }
// Save Original Size of the dialog
GetWindowRect (hwnd, &s_rcDialog);
// Never show details by default
s_fDetails = FALSE;
// Hide details drop down
if (s_fDetails == FALSE) { GetWindowRect(GetDlgItem (hwnd, idcIMProgSplitter), &rcDetails); cyDetails = s_rcDialog.bottom - rcDetails.top; MoveWindow(hwnd, s_rcDialog.left, s_rcDialog.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top - cyDetails - 1, FALSE); } else { AthLoadString(idsHideDetails, szRes, sizeof (szRes)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, idcIMProgSplitter), szRes); }
// Save the pointer
return 1;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam,lParam)) { case IDCANCEL: case IDOK: EndDialog(hwnd, IDOK); return 1;
case idbInetMailDetails: GetWindowRect (hwnd, &rcDlg); if (s_fDetails == FALSE) { MoveWindow(hwnd, rcDlg.left, rcDlg.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top, TRUE); AthLoadString(idsHideDetails, szRes, sizeof(szRes)/sizeof(TCHAR)); SetWindowText(GetDlgItem (hwnd, idbInetMailDetails), szRes); s_fDetails = TRUE; } else { GetWindowRect(GetDlgItem (hwnd, idcIMProgSplitter), &rcDetails); cyDetails = rcDlg.bottom - rcDetails.top; MoveWindow (hwnd, rcDlg.left, rcDlg.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top - cyDetails - 1, TRUE); AthLoadString (idsShowDetails, szRes, sizeof(szRes)/sizeof(TCHAR)); SetWindowText (GetDlgItem (hwnd, idbInetMailDetails), szRes); s_fDetails = FALSE; } } break; }
// Done
return 0; }
// =================================================================================
// SzGetSearchTokens
// =================================================================================
LPTSTR SzGetSearchTokens(LPTSTR pszCriteria) { // Locals
ULONG iCriteria=0, cbValueMax, cbTokens=0, cbValue, iSave; TCHAR chToken; LPTSTR pszValue=NULL, pszTokens=NULL; BOOL fTokenFound;
// Get Length of criteria
cbValueMax = lstrlen(pszCriteria) + 10; pszValue = SzStrAlloc(cbValueMax); if (!pszValue) goto exit;
// Alloc tokens list
pszTokens = SzStrAlloc(cbValueMax); if (!pszTokens) goto exit;
// Parse pszCriteria into space separated strings
while(1) { // Skip white space
SkipWhitespace (pszCriteria, &iCriteria);
// Save current position
iSave = iCriteria;
// Parse next token
fTokenFound = FStringTok (pszCriteria, &iCriteria, (LPTSTR)"\" ", &chToken, pszValue, cbValueMax, TRUE); if (!fTokenFound) break;
// Toke isn't a space ?
if (chToken == _T('"')) { // If something was found before the ", then it is a token
if (*pszValue) { cbValue = lstrlen(pszValue) + 1; Assert(cbTokens + cbValue <= cbValueMax); CopyMemory(pszTokens + cbTokens, pszValue, (int)min(cbValue,cbValueMax-cbTokens)); cbTokens+=cbValue; }
// Search for ending quote
fTokenFound = FStringTok (pszCriteria, &iCriteria, (LPTSTR)"\"", &chToken, pszValue, cbValueMax, TRUE); // Done ?
if (chToken == _T('\0')) { cbValue = lstrlen(pszValue) + 1; Assert(cbTokens + cbValue <= cbValueMax); CopyMemory(pszTokens + cbTokens, pszValue, (int)min(cbValue,cbValueMax-cbTokens)); cbTokens+=cbValue; break; }
else if (!fTokenFound || chToken != _T('\"')) { iCriteria = iSave + 1; continue; } }
// Add value to token list
cbValue = lstrlen(pszValue) + 1; Assert(cbTokens + cbValue <= cbValueMax); CopyMemory(pszTokens + cbTokens, pszValue, (int)min(cbValue,cbValueMax-cbTokens)); cbTokens+=cbValue;
// Done
if (chToken == _T('\0')) break; }
// Final NULL
*(pszTokens + cbTokens) = _T('\0'); exit: // Cleanup
SafeMemFree(pszValue);
// If no tokens, then free it
if (cbTokens == 0) { SafeMemFree(pszTokens); }
// Done
return pszTokens; }
// =================================================================================
// ProcessNlsError
// =================================================================================
VOID ProcessNlsError (VOID) { switch (GetLastError ()) { case ERROR_INSUFFICIENT_BUFFER: AssertSz (FALSE, "NLSAPI Error: ERROR_INSUFFICIENT_BUFFER"); break;
case ERROR_INVALID_FLAGS: AssertSz (FALSE, "NLSAPI Error: ERROR_INVALID_FLAGS"); break;
case ERROR_INVALID_PARAMETER: AssertSz (FALSE, "NLSAPI Error: ERROR_INVALID_PARAMETER"); break;
case ERROR_NO_UNICODE_TRANSLATION: AssertSz (FALSE, "NLSAPI Error: ERROR_NO_UNICODE_TRANSLATION"); break;
default: AssertSz (FALSE, "NLSAPI Error: <Un-resolved error>"); break; } }
#ifdef OLDSPOOLER
// =================================================================================
// SzGetLocalHostName
// =================================================================================
LPSTR SzGetLocalHostName (VOID) { // Locals
static char s_szLocalHost[255] = {0};
// Gets local host name from socket library
if (*s_szLocalHost == 0) { if (gethostname (s_szLocalHost, sizeof (s_szLocalHost)) == SOCKET_ERROR) { // $REVIEW - What should i do if this fails ???
Assert (FALSE); //DebugTrace ("gethostname failed: WSAGetLastError: %ld\n", WSAGetLastError ());
StrCpyNA(s_szLocalHost, "LocalHost", ARRAYSIZE(s_szLocalHost)); } }
// Done
return s_szLocalHost; }
// ==========================================================================
// StripIllegalHostChars
// ==========================================================================
VOID StripIllegalHostChars(LPSTR pszSrc, LPTSTR pszDst) { char ch;
while (ch = *pszSrc++) { if (ch <= 32 || ch >= 127 || ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '@' || ch == ',' || ch == ';' || ch == ':' || ch == '\\' || ch == '"' || ch == '[' || ch == ']' || ch == '`' || ch == '\'') continue; *pszDst++ = ch; }
*pszDst = 0; }
// ==========================================================================
// SzGetLocalHostNameForID
// ==========================================================================
LPSTR SzGetLocalHostNameForID (VOID) { // Locals
static char s_szLocalHostId[255] = {0};
// Gets local host name from socket library
if (*s_szLocalHostId == 0) { // Get Host name
LPSTR pszDst = s_szLocalHostId, pszSrc = SzGetLocalHostName();
// Strip illegals
StripIllegalHostChars(pszSrc, pszDst);
// if we stripped out everything, then just copy in something
if (*s_szLocalHostId == 0) StrCpyNA(s_szLocalHostId, "LocalHost", ARRAYSIZE(s_szLocalHostId)); } return s_szLocalHostId; }
// =================================================================================
// SzGetLocalPackedIP
// =================================================================================
LPTSTR SzGetLocalPackedIP (VOID) { // Locals
static TCHAR s_szLocalPackedIP[255] = {_T('\0')};
// Gets local host name from socket library
if (*s_szLocalPackedIP == _T('\0')) { LPHOSTENT hp = NULL;
hp = gethostbyname (SzGetLocalHostName ()); if (hp != NULL) wnsprintf(s_szLocalPackedIP, ARRAYSIZE(s_szLocalPackedIP), "%08x", *(long *)hp->h_addr);
else { // $REVIEW - What should i do if this fails ???
Assert (FALSE); //DebugTrace ("gethostbyname failed: WSAGetLastError: %ld\n", WSAGetLastError ());
StrCpyN(s_szLocalPackedIP, "LocalHost", ARRAYSIZE(s_szLocalPackedIP)); } }
// Done
return s_szLocalPackedIP; } #endif
// =============================================================================================
// SzGetNormalizedSubject
// =============================================================================================
LPTSTR SzNormalizeSubject (LPTSTR lpszSubject) { // Locals
LPTSTR lpszNormal = lpszSubject; ULONG i = 0, cch = 0, cbSubject;
// Bad Params
if (lpszSubject == NULL) goto exit;
// Les than 5 "xxx: "
cbSubject = lstrlen (lpszSubject); if (cbSubject < 4) goto exit;
// 1, 2, or 3 spaces followed by a ':' then a space
while (cch < 7 && i < cbSubject) { // Colon
if (lpszSubject[i] == _T(':')) { if (i+1 >= cbSubject) { // Should set to null terminator, nor subject
i+=1; lpszNormal = (LPTSTR)(lpszSubject + i); break; }
else if (cch <= 4 && lpszSubject[i+1] == _T(' ')) { i+=1; lpszNormal = (LPTSTR)(lpszSubject + i); i = 0; SkipWhitespace (lpszNormal, &i); lpszNormal += i; break; } else break; }
// Next Character
if (IsDBCSLeadByte (lpszSubject[i])) i+=2; else i++;
// Count Characters
cch++; }
exit: // Done
return lpszNormal; }
// =============================================================================================
// HrCopyAlloc
// =============================================================================================
HRESULT HrCopyAlloc (LPBYTE *lppbDest, LPBYTE lpbSrc, ULONG cb) { // Check Params
AssertSz (lppbDest && lpbSrc, "Null Parameter");
// Alloc Memory
if (!MemAlloc ((LPVOID *)lppbDest, cb)) return TRAPHR (hrMemory);
// Copy Memory
CopyMemory (*lppbDest, lpbSrc, cb);
// Done
return S_OK; }
// =============================================================================================
// StringDup - duplicates a string
// =============================================================================================
LPTSTR StringDup (LPCTSTR lpcsz) { // Locals
LPTSTR lpszDup;
if (lpcsz == NULL) return NULL;
INT nLen = lstrlen (lpcsz) + 1;
if (!MemAlloc ((LPVOID *)&lpszDup, nLen * sizeof (TCHAR))) return NULL;
CopyMemory (lpszDup, lpcsz, nLen * sizeof (TCHAR));
return lpszDup; }
// =============================================================================================
// SkipWhitespace
// Assumes piString points to character boundary
// =============================================================================================
void SkipWhitespace (LPCTSTR lpcsz, ULONG *pi) { if (!lpcsz || !pi) { Assert (FALSE); return; }
#ifdef DEBUG
Assert (*pi <= (ULONG)lstrlen (lpcsz)+1); #endif
LPTSTR lpsz = (LPTSTR)(lpcsz + *pi); while (*lpsz != _T('\0')) { if (!IsSpace(lpsz)) break;
if (IsDBCSLeadByte (*lpsz)) { lpsz+=2; (*pi)+=2; } else { lpsz++; (*pi)+=1; } }
return; }
// =============================================================================================
// Converts lpcsz to a UINT
// =============================================================================================
UINT AthUFromSz(LPCTSTR lpcsz) { // Locals
UINT u = 0, ch;
// Check Params
AssertSz (lpcsz, "Null parameter");
// Do Loop
LPTSTR lpsz = (LPTSTR)lpcsz; while ((ch = *lpsz) >= _T('0') && ch <= _T('9')) { u = u * 10 + ch - _T('0');
if (IsDBCSLeadByte (*lpsz)) lpsz+=2; else lpsz++; }
return u; }
// =============================================================================================
// Converts first two characters of lpcsz to a WORD
// =============================================================================================
WORD NFromSz (LPCTSTR lpcsz) { TCHAR acWordStr[3]; Assert (lpcsz); CopyMemory (acWordStr, lpcsz, 2 * sizeof (TCHAR)); acWordStr[2] = _T('\0'); return ((WORD) AthUFromSz (acWordStr)); }
// =============================================================================================
// FindChar
// =============================================================================================
LPTSTR SzFindChar (LPCTSTR lpcsz, TCHAR ch) { // Check Params
Assert (lpcsz);
// Local loop
LPTSTR lpsz = (LPTSTR)lpcsz;
// Loop string
while (*lpsz != _T('\0')) { if (*lpsz == ch) return lpsz;
if (IsDBCSLeadByte (*lpsz)) lpsz+=2; else lpsz++; }
return NULL; }
#ifdef DEAD
// =============================================================================================
// UlDBCSStripTrailingWhitespace
// =============================================================================================
ULONG UlDBCSStripWhitespace(LPSTR lpsz, BOOL fLeading, BOOL fTrailing, ULONG *pcb) { // Locals
ULONG cb=0, iLastSpace=0, cCharsSinceSpace=0; BOOL fLastCharSpace = FALSE;
// Get the string length
while (*lpsz) { if (cCharsSinceSpace && IsSpace(lpsz)) { cCharsSinceSpace=0; iLastSpace=cb; } else cCharsSinceSpace++;
if (IsDBCSLeadByte(*lpsz)) { lpsz+=2; cb+=2; } else { lpsz++; cb++; } }
if (cCharsSinceSpace == 0) { *(lpsz + iLastSpace) = _T('\0'); cb = iLastSpace - 1; }
// Set String Size
if (pcb) *pcb = cb; // Done
return cb; } #endif // DEAD
// =============================================================================================
// StringTok - similiar to strtok
// =============================================================================================
BOOL FStringTok (LPCTSTR lpcszString, ULONG *piString, LPTSTR lpcszTokens, TCHAR *chToken, LPTSTR lpszValue, ULONG cbValueMax, BOOL fStripTrailingWhitespace) { // Locals
LPTSTR lpszStringLoop, lpszTokenLoop; ULONG cbValue=0, nLen=0, cCharsSinceSpace=0, iLastSpace=0; BOOL fTokenFound = FALSE;
// Check Params
AssertSz (lpcszString && piString && lpcszTokens, "These should have been checked.");
// INit = better be on a dbcs boundary
lpszStringLoop = (LPTSTR)(lpcszString + (*piString));
// Loop current
while (*lpszStringLoop) { // If DBCS Lead Byte, skip it, it will never match the type of tokens I'm looking for
// Or, If an escape character, don't check delimiters
if (IsDBCSLeadByte(*lpszStringLoop) || *lpszStringLoop == _T('\\')) { cCharsSinceSpace+=2; lpszStringLoop+=2; cbValue+=2; continue; }
// Mark and remember last space
if (cCharsSinceSpace && IsSpace(lpszStringLoop)) { cCharsSinceSpace=0; iLastSpace=cbValue; }
// Count number of characters since last space
else cCharsSinceSpace++;
// Look for a tokens
lpszTokenLoop=lpcszTokens; while(*lpszTokenLoop) { // Token Match ?
if (*lpszStringLoop == *lpszTokenLoop) { // Save the found token
if (chToken) *chToken = *lpszStringLoop;
// Don't count this character as a charcter seen since last space
cCharsSinceSpace--;
// Were done
fTokenFound = TRUE; goto done; }
// Next Token
lpszTokenLoop++; }
// Next Char
lpszStringLoop++; cbValue++; }
done: // If reached end of string, this is a default token
if (*lpszStringLoop == _T('\0')) { if (chToken) *chToken = *lpszStringLoop; fTokenFound = TRUE; }
// Copy value if token found
if (fTokenFound) { if (lpszValue && cbValueMax > 0 && cbValue) { if (cbValue+1 <= cbValueMax) { StrCpyN (lpszValue, lpcszString + (*piString), cbValue+1); nLen = cbValue-1; } else { AssertSz (FALSE, "Buffer is too small."); StrCpyN (lpszValue, lpcszString + (*piString), cbValueMax); nLen = cbValueMax-1; }
// Strip Trailing Whitespace ?
if (fStripTrailingWhitespace && cCharsSinceSpace == 0) { *(lpszValue + iLastSpace) = _T('\0'); nLen = iLastSpace - 1; } }
// No Text
else { if (lpszValue) *lpszValue = _T('\0'); nLen = 0; cbValue = 0; }
// Set new string index
*piString += cbValue + 1; }
// Return whether we found a token
return fTokenFound; }
// =============================================================================================
// Return TRUE if string is empty or contains only spaces
// =============================================================================================
BOOL FIsStringEmpty (LPTSTR lpszString) { // Bad Pointer
if (!lpszString) return TRUE;
// Check for All spaces
for (; *lpszString != _T('\0'); lpszString++) { if (*lpszString != _T(' ')) return FALSE; }
// Done
return TRUE; }
BOOL FIsStringEmptyW(LPWSTR lpwszString) { // Bad Pointer
if (!lpwszString) return TRUE;
// Check for All spaces
for (; *lpwszString != L'\0'; lpwszString++) { if (*lpwszString != L' ') return FALSE; }
// Done
return TRUE; }
// =================================================================================
// Write some data to the blob
// =================================================================================
HRESULT HrBlobWriteData (LPBYTE lpbBlob, ULONG cbBlob, ULONG *pib, LPBYTE lpbData, ULONG cbData) { // Check Parameters
AssertSz (lpbBlob && cbBlob > 0 && pib && cbData > 0 && lpbData, "Bad Parameter"); AssertReadWritePtr (lpbBlob, cbData); AssertReadWritePtr (lpbData, cbData); AssertSz (*pib + cbData <= cbBlob, "Blob overflow");
// Copy Data Data
CopyMemory (lpbBlob + (*pib), lpbData, (int)min(cbData, cbBlob-(*pib))); *pib += cbData;
// Done
return S_OK; }
// =================================================================================
// Read some data from the blob
// =================================================================================
HRESULT HrBlobReadData (LPBYTE lpbBlob, ULONG cbBlob, ULONG *pib, LPBYTE lpbData, ULONG cbData) { // Check Parameters
AssertSz (lpbBlob && cbBlob > 0 && pib && cbData > 0 && lpbData, "Bad Parameter"); AssertReadWritePtr (lpbBlob, cbData); AssertReadWritePtr (lpbData, cbData); AssertSz (*pib + cbData <= cbBlob, "Blob overflow"); #ifdef WIN16 // When it happens it cause GPF in Win16, so rather than GPF, remove it from entry.
if ( *pib + cbData > cbBlob ) return E_FAIL; #endif
// Copy Data Data
CopyMemory (lpbData, lpbBlob + (*pib), cbData); *pib += cbData;
// Done
return S_OK; }
// =====================================================================================
// HrFixupHostString - In: saranac.microsoft.com Out: saranac
// =====================================================================================
HRESULT HrFixupHostString (LPTSTR lpszHost) { ULONG i = 0; TCHAR chToken;
if (lpszHost == NULL) return S_OK;
if (FStringTok (lpszHost, &i, _T("."), &chToken, NULL, 0, FALSE)) { if (chToken != _T('\0')) lpszHost[i-1] = _T('\0'); }
return S_OK; }
// =====================================================================================
// HrFixupAccountString - In: [email protected] Out: sbailey
// =====================================================================================
HRESULT HrFixupAccountString (LPTSTR lpszAccount) { ULONG i = 0; TCHAR chToken;
if (lpszAccount == NULL) return S_OK;
if (FStringTok (lpszAccount, &i, _T("@"), &chToken, NULL, 0, FALSE)) { if (chToken != _T('\0')) lpszAccount[i-1] = _T('\0'); }
return S_OK; }
// =====================================================================================
// HGetMenuFont
// =====================================================================================
HFONT HGetMenuFont (void) { #ifndef WIN16
// Locals
NONCLIENTMETRICS ncm; HFONT hFont = NULL;
// Create the menu font
ncm.cbSize = sizeof(NONCLIENTMETRICS); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (LPVOID)&ncm, 0)) { // Create Font
hFont = CreateFontIndirect(&ncm.lfMenuFont); }
// Done
return hFont; #else
LOGFONT lfMenu;
GetObject( GetStockObject( SYSTEM_FONT ), sizeof( lfMenu ), &lfMenu ); return( CreateFontIndirect( &lfMenu ) ); #endif
}
// =================================================================================
// CreateHGlobalFromStream
// =================================================================================
BOOL CreateHGlobalFromStream(LPSTREAM pstm, HGLOBAL * phg) { HGLOBAL hret = NULL; HGLOBAL hret2; LPBYTE lpb; ULONG cbRead = 0, cbSize = 1024;
if (!pstm || !phg) return FALSE; if (!(hret = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, cbSize))) return FALSE;
while (TRUE) { ULONG cb;
lpb = (LPBYTE)GlobalLock(hret); lpb += cbRead;
if (pstm->Read((LPVOID)lpb, 1024, &cb) != S_OK || cb < 1024) { cbRead += cb; GlobalUnlock(hret); break; }
cbRead += cb; cbSize += 1024;
GlobalUnlock(hret); hret2 = GlobalReAlloc(hret, cbSize, GMEM_MOVEABLE|GMEM_ZEROINIT); if (!hret2) return FALSE; hret = hret2; } if (hret) { hret2 = GlobalReAlloc(hret, cbRead, GMEM_MOVEABLE|GMEM_ZEROINIT); *phg = hret2; return TRUE; }
return FALSE; }
// =================================================================================
// HrDetailedError
// =================================================================================
VOID DetailedError (HWND hwndParent, LPDETERR lpDetErr) { // Check params
AssertSz (lpDetErr, "Null Parameter"); Assert (lpDetErr->lpszMessage && lpDetErr->lpszDetails);
// Beep
MessageBeep (MB_OK);
// Display Dialog Box
DialogBoxParam (g_hLocRes, MAKEINTRESOURCE (iddDetailedError), hwndParent, DetailedErrorDlgProc, (LPARAM)lpDetErr);
// Done
return; }
// =====================================================================================
// PasswordDlgProc
// =====================================================================================
INT_PTR CALLBACK DetailedErrorDlgProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { HANDLE_MSG (hwndDlg, WM_INITDIALOG, DetailedErrorDlgProc_OnInitDialog); HANDLE_MSG (hwndDlg, WM_COMMAND, DetailedErrorDlgProc_OnCommand); }
return 0; }
// =====================================================================================
// DetailedErrorDlgProc_OnInitDialog
// =====================================================================================
BOOL DetailedErrorDlgProc_OnInitDialog (HWND hwndDlg, HWND hwndFocus, LPARAM lParam) { // Locals
LPDETERR lpDetErr = NULL; TCHAR szTitle[255]; RECT rcDetails; ULONG cyDetails; TCHAR szButton[40];
// Center
CenterDialog (hwndDlg);
// Foreground
SetForegroundWindow (hwndDlg);
// Get Pass info struct
lpDetErr = (LPDETERR)lParam; if (lpDetErr == NULL) { Assert (FALSE); return 0; }
SetDlgThisPtr (hwndDlg, lpDetErr);
// Set Window Title
if (lpDetErr->idsTitle) if (AthLoadString (lpDetErr->idsTitle, szTitle, sizeof (szTitle))) SetWindowText (hwndDlg, szTitle);
// Show message
SetWindowText (GetDlgItem (hwndDlg, idcMessage), lpDetErr->lpszMessage);
if (FIsStringEmpty (lpDetErr->lpszDetails) == FALSE) SetWindowText (GetDlgItem (hwndDlg, ideDetails), lpDetErr->lpszDetails); else ShowWindow (GetDlgItem (hwndDlg, idbDetails), SW_HIDE);
// Save Original Size of the dialog
GetWindowRect (hwndDlg, &lpDetErr->rc);
// Hide Details box
if (lpDetErr->fHideDetails) { // Size of details
GetWindowRect (GetDlgItem (hwndDlg, idcSplit), &rcDetails);
// Height of details
cyDetails = lpDetErr->rc.bottom - rcDetails.top; // Re-size
MoveWindow (hwndDlg, lpDetErr->rc.left, lpDetErr->rc.top, lpDetErr->rc.right - lpDetErr->rc.left, lpDetErr->rc.bottom - lpDetErr->rc.top - cyDetails - 1, FALSE); }
else { // < Details
AthLoadString (idsHideDetails, szButton, ARRAYSIZE (szButton)); SetWindowText (GetDlgItem (hwndDlg, idbDetails), szButton); }
// Done
return FALSE; }
// =====================================================================================
// OnCommand
// =====================================================================================
void DetailedErrorDlgProc_OnCommand (HWND hwndDlg, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { HANDLE_COMMAND(hwndDlg, idbDetails, hwndCtl, codeNotify, DetailedErrorDlgProc_OnDetails); HANDLE_COMMAND(hwndDlg, IDOK, hwndCtl, codeNotify, DetailedErrorDlgProc_OnOk); HANDLE_COMMAND(hwndDlg, IDCANCEL, hwndCtl, codeNotify, DetailedErrorDlgProc_OnCancel); } return; }
// =====================================================================================
// OnCancel
// =====================================================================================
void DetailedErrorDlgProc_OnCancel (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode) { EndDialog (hwndDlg, IDCANCEL); }
// =====================================================================================
// OnOk
// =====================================================================================
void DetailedErrorDlgProc_OnOk (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode) { EndDialog (hwndDlg, IDOK); }
// =====================================================================================
// OnDetails
// =====================================================================================
void DetailedErrorDlgProc_OnDetails (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode) { // Locals
LPDETERR lpDetErr = NULL; RECT rcDlg, rcDetails; TCHAR szButton[40]; ULONG cyDetails;
// Get this
lpDetErr = (LPDETERR)GetDlgThisPtr (hwndDlg); if (lpDetErr == NULL) { Assert (FALSE); return; }
// Get current location of the dialog
GetWindowRect (hwndDlg, &rcDlg);
// If currently hidden
if (lpDetErr->fHideDetails) { // Re-size
MoveWindow (hwndDlg, rcDlg.left, rcDlg.top, lpDetErr->rc.right - lpDetErr->rc.left, lpDetErr->rc.bottom - lpDetErr->rc.top, TRUE);
// < Details
AthLoadString (idsHideDetails, szButton, sizeof (szButton)); SetWindowText (GetDlgItem (hwndDlg, idbDetails), szButton);
// Not Hidden
lpDetErr->fHideDetails = FALSE; }
else { // Size of details
GetWindowRect (GetDlgItem (hwndDlg, idcSplit), &rcDetails);
// Height of details
cyDetails = rcDlg.bottom - rcDetails.top; // Re-size
MoveWindow (hwndDlg, rcDlg.left, rcDlg.top, lpDetErr->rc.right - lpDetErr->rc.left, lpDetErr->rc.bottom - lpDetErr->rc.top - cyDetails - 1, TRUE);
// Details >
AthLoadString (idsShowDetails, szButton, sizeof (szButton)); SetWindowText (GetDlgItem (hwndDlg, idbDetails), szButton);
// Hidden
lpDetErr->fHideDetails = TRUE; } }
// =====================================================================================
// FIsLeapYear
// =====================================================================================
BOOL FIsLeapYear (INT nYear) { if (nYear % 4 == 0) { if ((nYear % 100) == 0 && (nYear % 400) != 0) return FALSE; else return TRUE; }
return FALSE; }
#ifdef DEBUG
VOID TestDateDiff (VOID) { SYSTEMTIME st; FILETIME ft1, ft2;
GetSystemTime (&st); SystemTimeToFileTime (&st, &ft2); st.wDay+=3; SystemTimeToFileTime (&st, &ft1); UlDateDiff (&ft1, &ft2); } #endif
// =====================================================================================
// Returns number of seconds between lpft1 and lpft2
// A leap year is defined as all years divisible by 4, except for years
// divisible by 100 that are not also divisible by 400. Years divisible by 400
// are leap years. 2000 is a leap year. 1900 is not a leap year.
// =====================================================================================
#define MAKEDWORDLONG(a, b) ((DWORDLONG)(((DWORD)(a)) | ((DWORDLONG)((DWORD)(b))) << 32))
#define LODWORD(l) ((DWORD)(l))
#define HIDWORD(l) ((DWORD)(((DWORDLONG)(l) >> 32) & 0xFFFFFFFF))
#define NANOSECONDS_INA_SECOND 10000000
ULONG UlDateDiff (LPFILETIME lpft1, LPFILETIME lpft2) { DWORDLONG dwl1, dwl2, dwlDiff; #ifndef WIN16
dwl1 = MAKEDWORDLONG(lpft1->dwLowDateTime, lpft1->dwHighDateTime); dwl2 = MAKEDWORDLONG(lpft2->dwLowDateTime, lpft2->dwHighDateTime); #else
dwl1 = ((__int64)(((DWORD)(lpft1->dwLowDateTime)) | ((__int64)((DWORD)(lpft1->dwHighDateTime))) << 32)); dwl2 = ((__int64)(((DWORD)(lpft2->dwLowDateTime)) | ((__int64)((DWORD)(lpft2->dwHighDateTime))) << 32)); #endif
// Make sure dwl1 is greater than dwl2
if (dwl2 > dwl1) { dwlDiff = dwl1; dwl1 = dwl2; dwl2 = dwlDiff; } dwlDiff = dwl1 - dwl2; dwlDiff = dwlDiff / NANOSECONDS_INA_SECOND; return ((ULONG) dwlDiff); }
// =====================================================================================
// StripSpaces
// =====================================================================================
VOID StripSpaces(LPTSTR psz) { UINT ib = 0; UINT cb = lstrlen(psz); TCHAR chT;
while (ib < cb) { // Get Character
chT = psz[ib];
// If lead byte, skip it, its leagal
if (IsDBCSLeadByte(chT)) ib+=2;
// Illeagl file name character ?
else if (chT == _T('\r') || chT == _T('\n') || chT == _T('\t') || chT == _T(' ')) { MoveMemory (psz + ib, psz + (ib + 1), cb - ib); cb--; } else ib++; } }
// =====================================================================================
// CProgress::CProgress
// =====================================================================================
CProgress::CProgress () { DOUT ("CProgress::CProgress"); m_cRef = 1; m_cMax = 0; m_cPerCur = 0; m_cCur = 0; m_hwndProgress = NULL; m_hwndDlg = NULL; m_hwndOwner = NULL; m_hwndDisable = NULL; m_fCanCancel = FALSE; m_fHasCancel = FALSE; m_cLast = 0; }
// =====================================================================================
// CProgress::~CProgress
// =====================================================================================
CProgress::~CProgress () { DOUT ("CProgress::~CProgress"); Close(); }
// =====================================================================================
// CProgress::AddRef
// =====================================================================================
ULONG CProgress::AddRef () { ++m_cRef; DOUT ("CProgress::AddRef () Ref Count=%d", m_cRef); return m_cRef; }
// =====================================================================================
// CProgress::AddRef
// =====================================================================================
ULONG CProgress::Release () { ULONG ulCount = --m_cRef; DOUT ("CProgress::Release () Ref Count=%d", ulCount); if (!ulCount) delete this; return ulCount; }
// =====================================================================================
// CProgress::Init
// =====================================================================================
VOID CProgress::Init (HWND hwndParent, LPTSTR lpszTitle, LPTSTR lpszMsg, ULONG cMax, UINT idani, BOOL fCanCancel, BOOL fBacktrackParent /* =TRUE */) { // Set Max and cur
m_cMax = cMax; m_cPerCur = 0; m_fCanCancel = fCanCancel; m_fHasCancel = FALSE;
// If dialog is not displayed yet
if (m_hwndDlg == NULL) { // Save Parent
m_hwndOwner = hwndParent;
// Find the topmost parent
m_hwndDisable = m_hwndOwner;
if (fBacktrackParent) { while(GetParent(m_hwndDisable)) m_hwndDisable = GetParent(m_hwndDisable); }
// Create Dialog
m_hwndDlg = CreateDialogParam (g_hLocRes, MAKEINTRESOURCE (iddProgress), hwndParent, ProgressDlgProc, (LPARAM)this);
}
// Otherwise, reset
else { // Stop and close animation
Animate_Close (GetDlgItem (m_hwndDlg, idcANI));
// Reset pos
Assert (m_hwndProgress); SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0); }
// Set title
SetTitle(lpszTitle);
// Set Message
SetMsg(lpszMsg);
// Animation ?
if (idani) { // Open the animation
Animate_OpenEx (GetDlgItem (m_hwndDlg, idcANI), g_hLocRes, MAKEINTRESOURCE(idani)); }
// No Cancel
if (FALSE == m_fCanCancel) { RECT rcDialog, rcProgress, rcCancel;
ShowWindow(GetDlgItem(m_hwndDlg, IDCANCEL), SW_HIDE); GetWindowRect(GetDlgItem(m_hwndDlg, IDCANCEL), &rcCancel); GetWindowRect(m_hwndDlg, &rcDialog); GetWindowRect(m_hwndProgress, &rcProgress); SetWindowPos(m_hwndProgress, NULL, 0, 0, rcDialog.right - rcProgress.left - (rcDialog.right - rcCancel.right), rcProgress.bottom - rcProgress.top, SWP_NOZORDER | SWP_NOMOVE); } }
// =====================================================================================
// CProgress::Close
// =====================================================================================
VOID CProgress::Close (VOID) { // If we have a window
if (m_hwndDlg) { // Close the animation
Animate_Close (GetDlgItem (m_hwndDlg, idcANI));
// Enable parent
if (m_hwndDisable) { EnableWindow (m_hwndDisable, TRUE); SetActiveWindow(m_hwndDisable); }
// Destroy it
DestroyWindow (m_hwndDlg);
// NULL
m_hwndDlg = NULL; } }
// =====================================================================================
// CProgress::Show
// =====================================================================================
VOID CProgress::Show (DWORD dwDelaySeconds) { // If we have a window
if (m_hwndDlg) { // Disable Parent
if (m_hwndDisable) EnableWindow (m_hwndDisable, FALSE);
// Start the animation
Animate_Play (GetDlgItem (m_hwndDlg, idcANI), 0, -1, -1);
// Show the window if now delay
if (dwDelaySeconds == 0) ShowWindow (m_hwndDlg, SW_SHOWNORMAL); else SetTimer(m_hwndDlg, IDT_PROGRESS_DELAY, dwDelaySeconds * 1000, NULL); } }
// =====================================================================================
// CProgress::Hide
// =====================================================================================
VOID CProgress::Hide (VOID) { // If we have a window
if (m_hwndDlg) { if (m_hwndDisable) EnableWindow(m_hwndDisable, TRUE); // Hide it
ShowWindow (m_hwndDlg, SW_HIDE);
// Stop the animation
Animate_Stop (GetDlgItem (m_hwndDlg, idcANI)); } }
// =====================================================================================
// CProgress::SetMsg
// =====================================================================================
VOID CProgress::SetMsg(LPTSTR lpszMsg) { TCHAR sz[CCHMAX_STRINGRES];
if (m_hwndDlg && lpszMsg) { if (IS_INTRESOURCE(lpszMsg)) { LoadString(g_hLocRes, PtrToUlong(lpszMsg), sz, sizeof(sz) / sizeof(TCHAR)); lpszMsg = sz; }
SetWindowText (GetDlgItem (m_hwndDlg, idsMsg), lpszMsg); } }
// =====================================================================================
// CProgress::SetTitle
// =====================================================================================
VOID CProgress::SetTitle(LPTSTR lpszTitle) { TCHAR sz[CCHMAX_STRINGRES];
if (m_hwndDlg && lpszTitle) { if (IS_INTRESOURCE(lpszTitle)) { LoadString(g_hLocRes, PtrToUlong(lpszTitle), sz, sizeof(sz) / sizeof(TCHAR)); lpszTitle = sz; }
SetWindowText (m_hwndDlg, lpszTitle); } }
// =====================================================================================
// CProgress::AdjustMax
// =====================================================================================
VOID CProgress::AdjustMax(ULONG cNewMax) { // Set Max
m_cMax = cNewMax;
// If 0
if (m_cMax == 0) { SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0); ShowWindow(m_hwndProgress, SW_HIDE); return; } else ShowWindow(m_hwndProgress, SW_SHOWNORMAL);
// If cur is now larget than max ?
if (m_cCur > m_cMax) m_cCur = m_cMax;
// Compute percent
m_cPerCur = (m_cCur * 100 / m_cMax);
// Update status
SendMessage (m_hwndProgress, PBM_SETPOS, m_cPerCur, 0);
// msgpump to process user moving window, or pressing cancel... :)
MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
VOID CProgress::Reset() { m_cCur = 0; m_cPerCur = 0;
// Update status
SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0); }
// =====================================================================================
// CProgress::HrUpdate
// =====================================================================================
HRESULT CProgress::HrUpdate (ULONG cInc) { // No max
if (m_cMax) { // Increment m_cCur
m_cCur += cInc;
// If cur is now larget than max ?
if (m_cCur > m_cMax) m_cCur = m_cMax;
// Compute percent
ULONG cPer = (m_cCur * 100 / m_cMax);
// Step percent
if (cPer > m_cPerCur) { // Set percur
m_cPerCur = cPer;
// Update status
SendMessage (m_hwndProgress, PBM_SETPOS, m_cPerCur, 0);
// msgpump to process user moving window, or pressing cancel... :)
MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } }
// Still pump some messages, call may not want to do this too often
else { // msgpump to process user moving window, or pressing cancel... :)
MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
// Done
return m_fHasCancel ? hrUserCancel : S_OK; }
// =====================================================================================
// CProgress::ProgressDlgProc
// =====================================================================================
INT_PTR CALLBACK CProgress::ProgressDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals
CProgress *lpProgress = (CProgress *)GetDlgThisPtr(hwnd); switch (uMsg) { case WM_INITDIALOG: lpProgress = (CProgress *)lParam; if (!lpProgress) { Assert (FALSE); return 1; } CenterDialog (hwnd); lpProgress->m_hwndProgress = GetDlgItem (hwnd, idcProgBar); if (lpProgress->m_cMax == 0) ShowWindow(lpProgress->m_hwndProgress, SW_HIDE); SetDlgThisPtr (hwnd, lpProgress); return 1;
case WM_TIMER: if (wParam == IDT_PROGRESS_DELAY) { KillTimer(hwnd, IDT_PROGRESS_DELAY); if (lpProgress->m_cPerCur < 80) { lpProgress->m_cMax -= lpProgress->m_cCur; lpProgress->Reset(); ShowWindow(hwnd, SW_SHOWNORMAL); } } break;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam,lParam)) { case IDCANCEL: if (lpProgress) { EnableWindow ((HWND)lParam, FALSE); lpProgress->m_fHasCancel = TRUE; } return 1; } break;
case WM_DESTROY: KillTimer(hwnd, IDT_PROGRESS_DELAY); SetDlgThisPtr (hwnd, NULL); break; }
// Done
return 0; }
// =====================================================================================
// ResizeDialogComboEx
// =====================================================================================
VOID ResizeDialogComboEx (HWND hwndDlg, HWND hwndCombo, UINT idcBase, HIMAGELIST himl) { // Locals
HDC hdc = NULL; HFONT hFont = NULL, hFontOld = NULL; TEXTMETRIC tm; RECT rectCombo; INT cxCombo = 0, cyCombo = 0, cxIcon = 0, cyIcon = 0, cyText; POINT pt;
// Get current font of combo box
hFont = (HFONT)SendMessage (GetDlgItem (hwndDlg, idcBase), WM_GETFONT, 0, 0); if (hFont == NULL) goto exit;
// Get a dc for the dialog
hdc = GetDC (hwndDlg); if (hdc == NULL) goto exit;
// Select font into dc
hFontOld = (HFONT)SelectObject (hdc, hFont);
// Get Text Metrics
GetTextMetrics (hdc, &tm);
// Comput sizeof combobox ex
GetWindowRect (hwndCombo, &rectCombo);
// Size of icon image
if (himl) ImageList_GetIconSize (himl, &cxIcon, &cyIcon);
// Sizeof combo
cxCombo = rectCombo.right - rectCombo.left; cyText = tm.tmHeight + tm.tmExternalLeading; cyCombo = max (cyIcon, cyText);
// Add a little extra
cyCombo += ((int)min (15, ComboBox_GetCount(hwndCombo)) * cyText);
// Map upper left of combo
pt.x = rectCombo.left; pt.y = rectCombo.top; MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rectCombo, 2); MoveWindow (hwndCombo, rectCombo.left, rectCombo.top, cxCombo, cyCombo, FALSE);
exit: // Cleanup
if (hdc) { // Select Old font
if (hFontOld) SelectObject (hdc, hFontOld);
// Delete DC
ReleaseDC (hwndDlg, hdc); }
// Done
return; }
|