Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

2270 lines (1818 sloc) 56.425 kb
/******************************************************************************
*
*
* Notepad2
*
* Helpers.c
* General helper functions
* Parts taken from SciTE, (c) Neil Hodgson, http://www.scintilla.org
* MinimizeToTray (c) 2000 Matthew Ellis
*
* See Readme.txt for more information about this source code.
* Please send me your comments to this work.
*
* See License.txt for details about distribution and modification.
*
* (c) Florian Balmer 1996-2010
* florian.balmer@gmail.com
* http://www.flos-freeware.ch
*
*
******************************************************************************/
#define _WIN32_WINNT 0x501
#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <commctrl.h>
#include <uxtheme.h>
#include <stdio.h>
#include <string.h>
#include "helpers.h"
#include "resource.h"
//=============================================================================
//
// Manipulation of (cached) ini file sections
//
int IniSectionGetString(
LPCWSTR lpCachedIniSection,
LPCWSTR lpName,
LPCWSTR lpDefault,
LPWSTR lpReturnedString,
int cchReturnedString)
{
WCHAR *p = (WCHAR *)lpCachedIniSection;
WCHAR tch[256];
int ich;
if (p) {
lstrcpy(tch,lpName);
lstrcat(tch,L"=");
ich = lstrlen(tch);
while (*p) {
if (StrCmpNI(p,tch,ich) == 0) {
lstrcpyn(lpReturnedString,p + ich,cchReturnedString);
return(lstrlen(lpReturnedString));
}
else
p = StrEnd(p) + 1;
}
}
lstrcpyn(lpReturnedString,lpDefault,cchReturnedString);
return(lstrlen(lpReturnedString));
}
int IniSectionGetInt(
LPCWSTR lpCachedIniSection,
LPCWSTR lpName,
int iDefault)
{
WCHAR *p = (WCHAR *)lpCachedIniSection;
WCHAR tch[256];
int ich;
int i;
if (p) {
lstrcpy(tch,lpName);
lstrcat(tch,L"=");
ich = lstrlen(tch);
while (*p) {
if (StrCmpNI(p,tch,ich) == 0) {
if (swscanf(p + ich,L"%i",&i) == 1)
return(i);
else
return(iDefault);
}
else
p = StrEnd(p) + 1;
}
}
return(iDefault);
}
BOOL IniSectionSetString(LPWSTR lpCachedIniSection,LPCWSTR lpName,LPCWSTR lpString)
{
WCHAR tch[32+512*3+32];
WCHAR *p = lpCachedIniSection;
if (p) {
while (*p) {
p = StrEnd(p) + 1;
}
wsprintf(tch,L"%s=%s",lpName,lpString);
lstrcpy(p,tch);
p = StrEnd(p) + 1;
*p = 0;
return(TRUE);
}
return(FALSE);
}
//=============================================================================
//
// BeginWaitCursor()
//
void BeginWaitCursor()
{
DestroyCursor(
SetCursor(
LoadCursor(NULL,IDC_WAIT)));
}
//=============================================================================
//
// EndWaitCursor()
//
void EndWaitCursor()
{
DestroyCursor(
SetCursor(
LoadCursor(NULL,IDC_ARROW)));
}
//=============================================================================
//
// PrivateIsAppThemed()
//
extern HMODULE hModUxTheme;
BOOL PrivateIsAppThemed()
{
FARPROC pfnIsAppThemed;
BOOL bIsAppThemed = FALSE;
if (hModUxTheme) {
pfnIsAppThemed = GetProcAddress(hModUxTheme,"IsAppThemed");
if (pfnIsAppThemed)
bIsAppThemed = pfnIsAppThemed();
}
return bIsAppThemed;
}
//=============================================================================
//
// PrivateSetCurrentProcessExplicitAppUserModelID()
//
HRESULT PrivateSetCurrentProcessExplicitAppUserModelID(PCWSTR AppID)
{
FARPROC pfnSetCurrentProcessExplicitAppUserModelID;
if (lstrlen(AppID) == 0)
return(S_OK);
if (lstrcmpi(AppID,L"(default)") == 0)
return(S_OK);
pfnSetCurrentProcessExplicitAppUserModelID =
GetProcAddress(GetModuleHandleA("shell32.dll"),"SetCurrentProcessExplicitAppUserModelID");
if (pfnSetCurrentProcessExplicitAppUserModelID)
return(pfnSetCurrentProcessExplicitAppUserModelID(AppID));
else
return(S_OK);
}
//=============================================================================
//
// IsElevated()
//
BOOL IsElevated() {
BOOL bIsElevated = FALSE;
HANDLE hToken = NULL;
if (!IsVista())
return(FALSE);
if (OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken)) {
struct {
DWORD TokenIsElevated;
} /*TOKEN_ELEVATION*/te;
DWORD dwReturnLength = 0;
if (GetTokenInformation(hToken,/*TokenElevation*/20,&te,sizeof(te),&dwReturnLength)) {
if (dwReturnLength == sizeof(te))
bIsElevated = te.TokenIsElevated;
}
CloseHandle( hToken );
}
return bIsElevated;
}
//=============================================================================
//
// SetExplorerTheme()
//
//BOOL SetExplorerTheme(HWND hwnd)
//{
// FARPROC pfnSetWindowTheme;
//
// if (IsVista()) {
// if (hModUxTheme) {
// pfnSetWindowTheme = GetProcAddress(hModUxTheme,"SetWindowTheme");
//
// if (pfnSetWindowTheme)
// return (S_OK == pfnSetWindowTheme(hwnd,L"Explorer",NULL));
// }
// }
// return FALSE;
//}
//=============================================================================
//
// VerifyContrast()
// Check if two colors can be distinguished
//
BOOL VerifyContrast(COLORREF cr1,COLORREF cr2)
{
BYTE r1 = GetRValue(cr1);
BYTE g1 = GetGValue(cr1);
BYTE b1 = GetBValue(cr1);
BYTE r2 = GetRValue(cr2);
BYTE g2 = GetGValue(cr2);
BYTE b2 = GetBValue(cr2);
return(
((abs((3*r1 + 5*g1 + 1*b1) - (3*r2 + 6*g2 + 1*b2))) >= 400) ||
((abs(r1-r2) + abs(b1-b2) + abs(g1-g2)) >= 400));
}
//=============================================================================
//
// SetWindowTitle()
//
BOOL bFreezeAppTitle = FALSE;
BOOL SetWindowTitle(HWND hwnd,UINT uIDAppName,BOOL bIsElevated,UINT uIDUntitled,
LPCWSTR lpszFile,int iFormat,BOOL bModified,
UINT uIDReadOnly,BOOL bReadOnly,LPCWSTR lpszExcerpt)
{
WCHAR szUntitled[128];
WCHAR szExcrptQuot[256];
WCHAR szExcrptFmt[32];
WCHAR szAppName[128];
WCHAR szElevatedAppName[128];
WCHAR szReadOnly[32];
WCHAR szTitle[512];
static const WCHAR *pszSep = L" - ";
static const WCHAR *pszMod = L"* ";
if (bFreezeAppTitle)
return FALSE;
if (!GetString(uIDAppName,szAppName,COUNTOF(szAppName)) ||
!GetString(uIDUntitled,szUntitled,COUNTOF(szUntitled)))
return FALSE;
if (bIsElevated) {
FormatString(szElevatedAppName,COUNTOF(szElevatedAppName),IDS_APPTITLE_ELEVATED,szAppName);
StrCpyN(szAppName,szElevatedAppName,COUNTOF(szAppName));
}
if (bModified)
lstrcpy(szTitle,pszMod);
else
lstrcpy(szTitle,L"");
if (lstrlen(lpszExcerpt)) {
GetString(IDS_TITLEEXCERPT,szExcrptFmt,COUNTOF(szExcrptFmt));
wsprintf(szExcrptQuot,szExcrptFmt,lpszExcerpt);
StrCat(szTitle,szExcrptQuot);
}
else if (lstrlen(lpszFile))
{
if (iFormat < 2 && !PathIsRoot(lpszFile))
{
SHFILEINFO shfi;
if (SHGetFileInfo2(lpszFile,0,&shfi,sizeof(SHFILEINFO),SHGFI_DISPLAYNAME))
lstrcat(szTitle,shfi.szDisplayName);
else
lstrcat(szTitle,PathFindFileName(lpszFile));
if (iFormat == 1) {
WCHAR tchPath[MAX_PATH];
StrCpyN(tchPath,lpszFile,COUNTOF(tchPath));
PathRemoveFileSpec(tchPath);
StrCat(szTitle,L" [");
StrCat(szTitle,tchPath);
StrCat(szTitle,L"]");
}
}
else
lstrcat(szTitle,lpszFile);
}
else
lstrcat(szTitle,szUntitled);
if (bReadOnly && GetString(uIDReadOnly,szReadOnly,COUNTOF(szReadOnly)))
{
lstrcat(szTitle,L" ");
lstrcat(szTitle,szReadOnly);
}
lstrcat(szTitle,pszSep);
lstrcat(szTitle,szAppName);
return SetWindowText(hwnd,szTitle);
}
//=============================================================================
//
// SetWindowTransparentMode()
//
void SetWindowTransparentMode(HWND hwnd,BOOL bTransparentMode)
{
FARPROC fp;
int iAlphaPercent;
BYTE bAlpha;
if (bTransparentMode) {
if (fp = GetProcAddress(GetModuleHandle(L"User32"),"SetLayeredWindowAttributes")) {
SetWindowLong(hwnd,GWL_EXSTYLE,
GetWindowLong(hwnd,GWL_EXSTYLE) | WS_EX_LAYERED);
// get opacity level from registry
iAlphaPercent = IniGetInt(L"Settings2",L"OpacityLevel",75);
if (iAlphaPercent < 0 || iAlphaPercent > 100)
iAlphaPercent = 75;
bAlpha = iAlphaPercent * 255 / 100;
fp(hwnd,0,bAlpha,LWA_ALPHA);
}
}
else
SetWindowLong(hwnd,GWL_EXSTYLE,
GetWindowLong(hwnd,GWL_EXSTYLE) & ~WS_EX_LAYERED);
}
//=============================================================================
//
// CenterDlgInParent()
//
void CenterDlgInParent(HWND hDlg)
{
RECT rcDlg;
HWND hParent;
RECT rcParent;
MONITORINFO mi;
HMONITOR hMonitor;
int xMin, yMin, xMax, yMax, x, y;
GetWindowRect(hDlg,&rcDlg);
hParent = GetParent(hDlg);
GetWindowRect(hParent,&rcParent);
hMonitor = MonitorFromRect(&rcParent,MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor,&mi);
xMin = mi.rcWork.left;
yMin = mi.rcWork.top;
xMax = (mi.rcWork.right) - (rcDlg.right - rcDlg.left);
yMax = (mi.rcWork.bottom) - (rcDlg.bottom - rcDlg.top);
if ((rcParent.right - rcParent.left) - (rcDlg.right - rcDlg.left) > 20)
x = rcParent.left + (((rcParent.right - rcParent.left) - (rcDlg.right - rcDlg.left)) / 2);
else
x = rcParent.left + 70;
if ((rcParent.bottom - rcParent.top) - (rcDlg.bottom - rcDlg.top) > 20)
y = rcParent.top + (((rcParent.bottom - rcParent.top) - (rcDlg.bottom - rcDlg.top)) / 2);
else
y = rcParent.top + 60;
SetWindowPos(hDlg,NULL,max(xMin,min(xMax,x)),max(yMin,min(yMax,y)),0,0,SWP_NOZORDER|SWP_NOSIZE);
}
//=============================================================================
//
// GetDlgPos()
//
void GetDlgPos(HWND hDlg,LPINT xDlg,LPINT yDlg)
{
RECT rcDlg;
HWND hParent;
RECT rcParent;
GetWindowRect(hDlg,&rcDlg);
hParent = GetParent(hDlg);
GetWindowRect(hParent,&rcParent);
// return positions relative to parent window
*xDlg = rcDlg.left - rcParent.left;
*yDlg = rcDlg.top - rcParent.top;
}
//=============================================================================
//
// SetDlgPos()
//
void SetDlgPos(HWND hDlg,int xDlg,int yDlg)
{
RECT rcDlg;
HWND hParent;
RECT rcParent;
MONITORINFO mi;
HMONITOR hMonitor;
int xMin, yMin, xMax, yMax, x, y;
GetWindowRect(hDlg,&rcDlg);
hParent = GetParent(hDlg);
GetWindowRect(hParent,&rcParent);
hMonitor = MonitorFromRect(&rcParent,MONITOR_DEFAULTTONEAREST);
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor,&mi);
xMin = mi.rcWork.left;
yMin = mi.rcWork.top;
xMax = (mi.rcWork.right) - (rcDlg.right - rcDlg.left);
yMax = (mi.rcWork.bottom) - (rcDlg.bottom - rcDlg.top);
// desired positions relative to parent window
x = rcParent.left + xDlg;
y = rcParent.top + yDlg;
SetWindowPos(hDlg,NULL,max(xMin,min(xMax,x)),max(yMin,min(yMax,y)),0,0,SWP_NOZORDER|SWP_NOSIZE);
}
//=============================================================================
//
// Resize Dialog Helpers()
//
typedef struct _resizedlg {
int cxClient;
int cyClient;
int cxFrame;
int cyFrame;
int mmiPtMinX;
int mmiPtMinY;
} RESIZEDLG, *PRESIZEDLG;
void ResizeDlg_Init(HWND hwnd,int cxFrame,int cyFrame,int nIdGrip)
{
RECT rc;
WCHAR wch[64];
int cGrip;
RESIZEDLG *pm = LocalAlloc(LPTR,sizeof(RESIZEDLG));
GetClientRect(hwnd,&rc);
pm->cxClient = rc.right - rc.left;
pm->cyClient = rc.bottom - rc.top;
pm->cxFrame = cxFrame;
pm->cyFrame = cyFrame;
AdjustWindowRectEx(&rc,GetWindowLongPtr(hwnd,GWL_STYLE)|WS_THICKFRAME,FALSE,0);
pm->mmiPtMinX = rc.right-rc.left;
pm->mmiPtMinY = rc.bottom-rc.top;
if (pm->cxFrame < (rc.right-rc.left))
pm->cxFrame = rc.right-rc.left;
if (pm->cyFrame < (rc.bottom-rc.top))
pm->cyFrame = rc.bottom-rc.top;
SetProp(hwnd,L"ResizeDlg",(HANDLE)pm);
SetWindowPos(hwnd,NULL,rc.left,rc.top,pm->cxFrame,pm->cyFrame,SWP_NOZORDER);
SetWindowLongPtr(hwnd,GWL_STYLE,GetWindowLongPtr(hwnd,GWL_STYLE)|WS_THICKFRAME);
SetWindowPos(hwnd,NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
GetMenuString(GetSystemMenu(GetParent(hwnd),FALSE),SC_SIZE,wch,COUNTOF(wch),MF_BYCOMMAND);
InsertMenu(GetSystemMenu(hwnd,FALSE),SC_CLOSE,MF_BYCOMMAND|MF_STRING|MF_ENABLED,SC_SIZE,wch);
InsertMenu(GetSystemMenu(hwnd,FALSE),SC_CLOSE,MF_BYCOMMAND|MF_SEPARATOR,0,NULL);
SetWindowLongPtr(GetDlgItem(hwnd,nIdGrip),GWL_STYLE,
GetWindowLongPtr(GetDlgItem(hwnd,nIdGrip),GWL_STYLE)|SBS_SIZEGRIP|WS_CLIPSIBLINGS);
cGrip = GetSystemMetrics(SM_CXHTHUMB);
SetWindowPos(GetDlgItem(hwnd,nIdGrip),NULL,pm->cxClient-cGrip,pm->cyClient-cGrip,cGrip,cGrip,SWP_NOZORDER);
}
void ResizeDlg_Destroy(HWND hwnd,int *cxFrame,int *cyFrame)
{
RECT rc;
PRESIZEDLG pm = GetProp(hwnd,L"ResizeDlg");
GetWindowRect(hwnd,&rc);
*cxFrame = rc.right-rc.left;
*cyFrame = rc.bottom-rc.top;
RemoveProp(hwnd,L"ResizeDlg");
LocalFree(pm);
}
void ResizeDlg_Size(HWND hwnd,LPARAM lParam,int *cx,int *cy)
{
PRESIZEDLG pm = GetProp(hwnd,L"ResizeDlg");
*cx = LOWORD(lParam) - pm->cxClient;
*cy = HIWORD(lParam) - pm->cyClient;
pm->cxClient = LOWORD(lParam);
pm->cyClient = HIWORD(lParam);
}
void ResizeDlg_GetMinMaxInfo(HWND hwnd,LPARAM lParam)
{
PRESIZEDLG pm = GetProp(hwnd,L"ResizeDlg");
LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam;
lpmmi->ptMinTrackSize.x = pm->mmiPtMinX;
lpmmi->ptMinTrackSize.y = pm->mmiPtMinY;
}
HDWP DeferCtlPos(HDWP hdwp,HWND hwndDlg,int nCtlId,int dx,int dy,UINT uFlags)
{
RECT rc;
HWND hwndCtl = GetDlgItem(hwndDlg,nCtlId);
GetWindowRect(hwndCtl,&rc);
MapWindowPoints(NULL,hwndDlg,(LPPOINT)&rc,2);
if (uFlags & SWP_NOSIZE)
return(DeferWindowPos(hdwp,hwndCtl,NULL,rc.left+dx,rc.top+dy,0,0,SWP_NOZORDER|SWP_NOSIZE));
else
return(DeferWindowPos(hdwp,hwndCtl,NULL,0,0,rc.right-rc.left+dx,rc.bottom-rc.top+dy,SWP_NOZORDER|SWP_NOMOVE));
}
//=============================================================================
//
// MakeBitmapButton()
//
void MakeBitmapButton(HWND hwnd,int nCtlId,HINSTANCE hInstance,UINT uBmpId)
{
HWND hwndCtl = GetDlgItem(hwnd,nCtlId);
BITMAP bmp;
BUTTON_IMAGELIST bi;
HBITMAP hBmp = LoadImage(hInstance,MAKEINTRESOURCE(uBmpId),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
GetObject(hBmp,sizeof(BITMAP),&bmp);
bi.himl = ImageList_Create(bmp.bmWidth,bmp.bmHeight,ILC_COLOR32|ILC_MASK,1,0);
ImageList_AddMasked(bi.himl,hBmp,CLR_DEFAULT);
DeleteObject(hBmp);
SetRect(&bi.margin,0,0,0,0);
bi.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
SendMessage(hwndCtl,BCM_SETIMAGELIST,0,(LPARAM)&bi);
}
//=============================================================================
//
// MakeColorPickButton()
//
void MakeColorPickButton(HWND hwnd,int nCtlId,HINSTANCE hInstance,COLORREF crColor)
{
HWND hwndCtl = GetDlgItem(hwnd,nCtlId);
BUTTON_IMAGELIST bi;
HIMAGELIST himlOld = NULL;
HBITMAP hBmp;
COLORMAP colormap[2];
if (SendMessage(hwndCtl,BCM_GETIMAGELIST,0,(LPARAM)&bi))
himlOld = bi.himl;
if (IsWindowEnabled(hwndCtl) && crColor != -1) {
colormap[0].from = RGB(0x00,0x00,0x00);
colormap[0].to = GetSysColor(COLOR_3DSHADOW);
}
else {
colormap[0].from = RGB(0x00,0x00,0x00);
colormap[0].to = RGB(0xFF,0xFF,0xFF);
}
if (IsWindowEnabled(hwndCtl) && crColor != -1) {
if (crColor == RGB(0xFF,0xFF,0xFF))
crColor = RGB(0xFF,0xFF,0xFE);
colormap[1].from = RGB(0xFF,0xFF,0xFF);
colormap[1].to = crColor;
}
else {
colormap[1].from = RGB(0xFF,0xFF,0xFF);
colormap[1].to = RGB(0xFF,0xFF,0xFF);
}
hBmp = CreateMappedBitmap(hInstance,IDB_PICK,0,colormap,2);
bi.himl = ImageList_Create(10,10,ILC_COLORDDB|ILC_MASK,1,0);
ImageList_AddMasked(bi.himl,hBmp,RGB(0xFF,0xFF,0xFF));
DeleteObject(hBmp);
SetRect(&bi.margin,0,0,4,0);
bi.uAlign = BUTTON_IMAGELIST_ALIGN_RIGHT;
SendMessage(hwndCtl,BCM_SETIMAGELIST,0,(LPARAM)&bi);
InvalidateRect(hwndCtl,NULL,TRUE);
if (himlOld)
ImageList_Destroy(himlOld);
}
//=============================================================================
//
// DeleteBitmapButton()
//
void DeleteBitmapButton(HWND hwnd,int nCtlId)
{
HWND hwndCtl = GetDlgItem(hwnd,nCtlId);
BUTTON_IMAGELIST bi;
if (SendMessage(hwndCtl,BCM_GETIMAGELIST,0,(LPARAM)&bi))
ImageList_Destroy(bi.himl);
}
//=============================================================================
//
// StatusSetText()
//
BOOL StatusSetText(HWND hwnd,UINT nPart,LPCWSTR lpszText)
{
UINT uFlags = (nPart == 255) ? nPart|SBT_NOBORDERS : nPart;
return SendMessage(hwnd,SB_SETTEXT,uFlags,(LPARAM)lpszText);
}
//=============================================================================
//
// SendWMSize()
//
LRESULT SendWMSize(HWND hwnd)
{
RECT rc; GetClientRect(hwnd,&rc);
return(SendMessage(hwnd,WM_SIZE,SIZE_RESTORED,
MAKELPARAM(rc.right,rc.bottom)));
}
//=============================================================================
//
// StatusSetTextID()
//
BOOL StatusSetTextID(HWND hwnd,UINT nPart,UINT uID)
{
WCHAR szText[256];
UINT uFlags = (nPart == 255) ? nPart|SBT_NOBORDERS : nPart;
if (!uID)
{
SendMessage(hwnd,SB_SETTEXT,uFlags,0);
return TRUE;
}
if (!GetString(uID,szText,256))
return FALSE;
return SendMessage(hwnd,SB_SETTEXT,uFlags,(LPARAM)szText);
}
//=============================================================================
//
// StatusCalcPaneWidth()
//
int StatusCalcPaneWidth(HWND hwnd,LPCWSTR lpsz)
{
SIZE size;
HDC hdc = GetDC(hwnd);
HFONT hfont = (HFONT)SendMessage(hwnd,WM_GETFONT,0,0);
HFONT hfold = SelectObject(hdc,hfont);
int mmode = SetMapMode(hdc,MM_TEXT);
GetTextExtentPoint32(hdc,lpsz,lstrlen(lpsz),&size);
SetMapMode(hdc,mmode);
SelectObject(hdc,hfold);
ReleaseDC(hwnd,hdc);
return(size.cx + 9);
}
//=============================================================================
//
// Toolbar_Get/SetButtons()
//
int Toolbar_GetButtons(HWND hwnd,int cmdBase,LPWSTR lpszButtons,int cchButtons)
{
WCHAR tchButtons[512];
WCHAR tchItem[32];
int i,c;
TBBUTTON tbb;
lstrcpy(tchButtons,L"");
c = min(50,SendMessage(hwnd,TB_BUTTONCOUNT,0,0));
for (i = 0; i < c; i++) {
SendMessage(hwnd,TB_GETBUTTON,(WPARAM)i,(LPARAM)&tbb);
wsprintf(tchItem,L"%i ",
(tbb.idCommand==0)?0:tbb.idCommand-cmdBase+1);
lstrcat(tchButtons,tchItem);
}
TrimString(tchButtons);
lstrcpyn(lpszButtons,tchButtons,cchButtons);
return(c);
}
int Toolbar_SetButtons(HWND hwnd,int cmdBase,LPCWSTR lpszButtons,LPCTBBUTTON ptbb,int ctbb)
{
WCHAR tchButtons[512];
WCHAR *p;
int i,c;
int iCmd;
ZeroMemory(tchButtons,COUNTOF(tchButtons)*sizeof(tchButtons[0]));
lstrcpyn(tchButtons,lpszButtons,COUNTOF(tchButtons)-2);
TrimString(tchButtons);
while (p = StrStr(tchButtons,L" "))
MoveMemory((WCHAR*)p,(WCHAR*)p+1,(lstrlen(p) + 1) * sizeof(WCHAR));
c = SendMessage(hwnd,TB_BUTTONCOUNT,0,0);
for (i = 0; i < c; i++)
SendMessage(hwnd,TB_DELETEBUTTON,0,0);
for (i = 0; i < COUNTOF(tchButtons); i++)
if (tchButtons[i] == L' ') tchButtons[i] = 0;
p = tchButtons;
while (*p) {
if (swscanf(p,L"%i",&iCmd) == 1) {
iCmd = (iCmd==0)?0:iCmd+cmdBase-1;
for (i = 0; i < ctbb; i++) {
if (ptbb[i].idCommand == iCmd) {
SendMessage(hwnd,TB_ADDBUTTONS,(WPARAM)1,(LPARAM)&ptbb[i]);
break;
}
}
}
p = StrEnd(p)+1;
}
return(SendMessage(hwnd,TB_BUTTONCOUNT,0,0));
}
//=============================================================================
//
// IsCmdEnabled()
//
BOOL IsCmdEnabled(HWND hwnd,UINT uId)
{
HMENU hmenu;
UINT ustate;
hmenu = GetMenu(hwnd);
SendMessage(hwnd,WM_INITMENU,(WPARAM)hmenu,0);
ustate = GetMenuState(hmenu,uId,MF_BYCOMMAND);
if (ustate == 0xFFFFFFFF)
return TRUE;
else
return (!(ustate & (MF_GRAYED|MF_DISABLED)));
}
//=============================================================================
//
// FormatString()
//
int FormatString(LPWSTR lpOutput,int nOutput,UINT uIdFormat,...)
{
WCHAR *p = LocalAlloc(LPTR,sizeof(WCHAR)*nOutput);
if (GetString(uIdFormat,p,nOutput))
wvsprintf(lpOutput,p,(LPVOID)((PUINT_PTR)&uIdFormat+1));
LocalFree(p);
return lstrlen(lpOutput);
}
//=============================================================================
//
// PathRelativeToApp()
//
void PathRelativeToApp(
LPWSTR lpszSrc,LPWSTR lpszDest,int cchDest,BOOL bSrcIsFile,
BOOL bUnexpandEnv,BOOL bUnexpandMyDocs) {
WCHAR wchAppPath[MAX_PATH];
WCHAR wchWinDir[MAX_PATH];
WCHAR wchUserFiles[MAX_PATH];
WCHAR wchPath[MAX_PATH];
WCHAR wchResult[MAX_PATH];
DWORD dwAttrTo = (bSrcIsFile) ? 0 : FILE_ATTRIBUTE_DIRECTORY;
GetModuleFileName(NULL,wchAppPath,COUNTOF(wchAppPath));
PathRemoveFileSpec(wchAppPath);
GetWindowsDirectory(wchWinDir,COUNTOF(wchWinDir));
SHGetFolderPath(NULL,CSIDL_PERSONAL,NULL,SHGFP_TYPE_CURRENT,wchUserFiles);
if (bUnexpandMyDocs &&
!PathIsRelative(lpszSrc) &&
!PathIsPrefix(wchUserFiles,wchAppPath) &&
PathIsPrefix(wchUserFiles,lpszSrc) &&
PathRelativePathTo(wchPath,wchUserFiles,FILE_ATTRIBUTE_DIRECTORY,lpszSrc,dwAttrTo)) {
lstrcpy(wchUserFiles,L"%CSIDL:MYDOCUMENTS%");
PathAppend(wchUserFiles,wchPath);
lstrcpy(wchPath,wchUserFiles);
}
else if (PathIsRelative(lpszSrc) || PathCommonPrefix(wchAppPath,wchWinDir,NULL))
lstrcpyn(wchPath,lpszSrc,COUNTOF(wchPath));
else {
if (!PathRelativePathTo(wchPath,wchAppPath,FILE_ATTRIBUTE_DIRECTORY,lpszSrc,dwAttrTo))
lstrcpyn(wchPath,lpszSrc,COUNTOF(wchPath));
}
if (bUnexpandEnv) {
if (!PathUnExpandEnvStrings(wchPath,wchResult,COUNTOF(wchResult)))
lstrcpyn(wchResult,wchPath,COUNTOF(wchResult));
}
else
lstrcpyn(wchResult,wchPath,COUNTOF(wchResult));
if (lpszDest == NULL || lpszSrc == lpszDest)
lstrcpyn(lpszSrc,wchResult,(cchDest == 0) ? MAX_PATH : cchDest);
else
lstrcpyn(lpszDest,wchResult,(cchDest == 0) ? MAX_PATH : cchDest);
}
//=============================================================================
//
// PathAbsoluteFromApp()
//
void PathAbsoluteFromApp(LPWSTR lpszSrc,LPWSTR lpszDest,int cchDest,BOOL bExpandEnv) {
WCHAR wchPath[MAX_PATH];
WCHAR wchResult[MAX_PATH];
if (StrCmpNI(lpszSrc,L"%CSIDL:MYDOCUMENTS%",COUNTOF("%CSIDL:MYDOCUMENTS%")-1) == 0) {
SHGetFolderPath(NULL,CSIDL_PERSONAL,NULL,SHGFP_TYPE_CURRENT,wchPath);
PathAppend(wchPath,lpszSrc+COUNTOF("%CSIDL:MYDOCUMENTS%")-1);
}
else
lstrcpyn(wchPath,lpszSrc,COUNTOF(wchPath));
if (bExpandEnv)
ExpandEnvironmentStringsEx(wchPath,COUNTOF(wchPath));
if (PathIsRelative(wchPath)) {
GetModuleFileName(NULL,wchResult,COUNTOF(wchResult));
PathRemoveFileSpec(wchResult);
PathAppend(wchResult,wchPath);
}
else
lstrcpyn(wchResult,wchPath,COUNTOF(wchResult));
PathCanonicalizeEx(wchResult);
if (PathGetDriveNumber(wchResult) != -1)
CharUpperBuff(wchResult,1);
if (lpszDest == NULL || lpszSrc == lpszDest)
lstrcpyn(lpszSrc,wchResult,(cchDest == 0) ? MAX_PATH : cchDest);
else
lstrcpyn(lpszDest,wchResult,(cchDest == 0) ? MAX_PATH : cchDest);
}
///////////////////////////////////////////////////////////////////////////////
//
//
// Name: PathIsLnkFile()
//
// Purpose: Determine wheter pszPath is a Windows Shell Link File by
// comparing the filename extension with L".lnk"
//
// Manipulates:
//
BOOL PathIsLnkFile(LPCWSTR pszPath)
{
//WCHAR *pszExt;
WCHAR tchResPath[256];
if (!pszPath || !*pszPath)
return FALSE;
/*pszExt = StrRChr(pszPath,NULL,L'.');
if (!pszExt)
return FALSE;
if (!lstrcmpi(pszExt,L".lnk"))
return TRUE;
else
return FALSE;*/
//if (!lstrcmpi(PathFindExtension(pszPath),L".lnk"))
// return TRUE;
//else
// return FALSE;
if (lstrcmpi(PathFindExtension(pszPath),L".lnk"))
return FALSE;
else
return PathGetLnkPath(pszPath,tchResPath,COUNTOF(tchResPath));
}
///////////////////////////////////////////////////////////////////////////////
//
//
// Name: PathGetLnkPath()
//
// Purpose: Try to get the path to which a lnk-file is linked
//
//
// Manipulates: pszResPath
//
BOOL PathGetLnkPath(LPCWSTR pszLnkFile,LPWSTR pszResPath,int cchResPath)
{
IShellLink *psl;
WIN32_FIND_DATA fd;
BOOL bSucceeded = FALSE;
if (SUCCEEDED(CoCreateInstance(&CLSID_ShellLink,NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLink,&psl)))
{
IPersistFile *ppf;
if (SUCCEEDED(psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile,&ppf)))
{
WORD wsz[MAX_PATH];
/*MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,
pszLnkFile,-1,wsz,MAX_PATH);*/
lstrcpy(wsz,pszLnkFile);
if (SUCCEEDED(ppf->lpVtbl->Load(ppf,wsz,STGM_READ)))
{
if (NOERROR == psl->lpVtbl->GetPath(psl,pszResPath,cchResPath,&fd,0))
bSucceeded = TRUE;
}
ppf->lpVtbl->Release(ppf);
}
psl->lpVtbl->Release(psl);
}
// This additional check seems reasonable
if (!lstrlen(pszResPath))
bSucceeded = FALSE;
if (bSucceeded) {
ExpandEnvironmentStringsEx(pszResPath,cchResPath);
PathCanonicalizeEx(pszResPath);
}
return(bSucceeded);
}
///////////////////////////////////////////////////////////////////////////////
//
//
// Name: PathIsLnkToDirectory()
//
// Purpose: Determine wheter pszPath is a Windows Shell Link File which
// refers to a directory
//
// Manipulates: pszResPath
//
BOOL PathIsLnkToDirectory(LPCWSTR pszPath,LPWSTR pszResPath,int cchResPath)
{
WCHAR tchResPath[MAX_PATH];
if (PathIsLnkFile(pszPath)) {
if (PathGetLnkPath(pszPath,tchResPath,sizeof(WCHAR)*COUNTOF(tchResPath))) {
if (PathIsDirectory(tchResPath)) {
lstrcpyn(pszResPath,tchResPath,cchResPath);
return (TRUE);
}
else
return FALSE;
}
else
return FALSE;
}
else
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
//
//
// Name: PathCreateDeskLnk()
//
// Purpose: Modified to create a desktop link to Notepad2
//
// Manipulates:
//
BOOL PathCreateDeskLnk(LPCWSTR pszDocument)
{
WCHAR tchExeFile[MAX_PATH];
WCHAR tchDocTemp[MAX_PATH];
WCHAR tchArguments[MAX_PATH+16];
WCHAR tchLinkDir[MAX_PATH];
WCHAR tchDescription[64];
WCHAR tchLnkFileName[MAX_PATH];
IShellLink *psl;
BOOL bSucceeded = FALSE;
BOOL fMustCopy;
if (!pszDocument || lstrlen(pszDocument) == 0)
return TRUE;
// init strings
GetModuleFileName(NULL,tchExeFile,COUNTOF(tchExeFile));
lstrcpy(tchDocTemp,pszDocument);
PathQuoteSpaces(tchDocTemp);
lstrcpy(tchArguments,L"-n ");
lstrcat(tchArguments,tchDocTemp);
SHGetSpecialFolderPath(NULL,tchLinkDir,CSIDL_DESKTOP,TRUE);
GetString(IDS_LINKDESCRIPTION,tchDescription,COUNTOF(tchDescription));
// Try to construct a valid filename...
if (!SHGetNewLinkInfo(pszDocument,tchLinkDir,tchLnkFileName,&fMustCopy,SHGNLI_PREFIXNAME))
return(FALSE);
if (SUCCEEDED(CoCreateInstance(&CLSID_ShellLink,NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLink,&psl)))
{
IPersistFile *ppf;
if (SUCCEEDED(psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile,&ppf)))
{
WORD wsz[MAX_PATH];
/*MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,
tchLnkFileName,-1,wsz,MAX_PATH);*/
lstrcpy(wsz,tchLnkFileName);
psl->lpVtbl->SetPath(psl,tchExeFile);
psl->lpVtbl->SetArguments(psl,tchArguments);
psl->lpVtbl->SetDescription(psl,tchDescription);
if (SUCCEEDED(ppf->lpVtbl->Save(ppf,wsz,TRUE)))
bSucceeded = TRUE;
ppf->lpVtbl->Release(ppf);
}
psl->lpVtbl->Release(psl);
}
return(bSucceeded);
}
///////////////////////////////////////////////////////////////////////////////
//
//
// Name: PathCreateFavLnk()
//
// Purpose: Modified to create a Notepad2 favorites link
//
// Manipulates:
//
BOOL PathCreateFavLnk(LPCWSTR pszName,LPCWSTR pszTarget,LPCWSTR pszDir)
{
WCHAR tchLnkFileName[MAX_PATH];
IShellLink *psl;
BOOL bSucceeded = FALSE;
if (!pszName || lstrlen(pszName) == 0)
return TRUE;
lstrcpy(tchLnkFileName,pszDir);
PathAppend(tchLnkFileName,pszName);
lstrcat(tchLnkFileName,L".lnk");
if (PathFileExists(tchLnkFileName))
return FALSE;
if (SUCCEEDED(CoCreateInstance(&CLSID_ShellLink,NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLink,&psl)))
{
IPersistFile *ppf;
if (SUCCEEDED(psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile,&ppf)))
{
WORD wsz[MAX_PATH];
/*MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,
tchLnkFileName,-1,wsz,MAX_PATH);*/
lstrcpy(wsz,tchLnkFileName);
psl->lpVtbl->SetPath(psl,pszTarget);
if (SUCCEEDED(ppf->lpVtbl->Save(ppf,wsz,TRUE)))
bSucceeded = TRUE;
ppf->lpVtbl->Release(ppf);
}
psl->lpVtbl->Release(psl);
}
return(bSucceeded);
}
//=============================================================================
//
// TrimString()
//
BOOL TrimString(LPWSTR lpString)
{
LPWSTR psz;
if (!lpString || !*lpString)
return FALSE;
// Trim left
psz = lpString;
while (*psz == L' ')
psz = CharNext(psz);
MoveMemory(lpString,psz,sizeof(WCHAR)*(lstrlen(psz) + 1));
// Trim right
psz = StrEnd(lpString);
while (*(psz = CharPrev(lpString,psz)) == L' ')
*psz = L'\0';
return TRUE;
}
//=============================================================================
//
// ExtractFirstArgument()
//
BOOL ExtractFirstArgument(LPCWSTR lpArgs,LPWSTR lpArg1,LPWSTR lpArg2)
{
LPWSTR psz;
BOOL bQuoted = FALSE;
lstrcpy(lpArg1,lpArgs);
if (lpArg2)
*lpArg2 = L'\0';
if (!TrimString(lpArg1))
return FALSE;
if (*lpArg1 == L'\"')
{
*lpArg1 = L' ';
TrimString(lpArg1);
bQuoted = TRUE;
}
if (bQuoted)
psz = StrChr(lpArg1,L'\"');
else
psz = StrChr(lpArg1,L' ');;
if (psz)
{
*psz = L'\0';
if (lpArg2)
lstrcpy(lpArg2,psz + 1);
}
TrimString(lpArg1);
if (lpArg2)
TrimString(lpArg2);
return TRUE;
}
//=============================================================================
//
// PrepareFilterStr()
//
void PrepareFilterStr(LPWSTR lpFilter)
{
LPWSTR psz = StrEnd(lpFilter);
while (psz != lpFilter)
{
if (*(psz = CharPrev(lpFilter,psz)) == L'|')
*psz = L'\0';
}
}
//=============================================================================
//
// StrTab2Space() - in place conversion
//
void StrTab2Space(LPWSTR lpsz)
{
WCHAR *c;
while (c = StrChr(lpsz,L'\t'))
*c = L' ';
}
//=============================================================================
//
// ExpandEnvironmentStringsEx()
//
// Adjusted for Windows 95
//
void ExpandEnvironmentStringsEx(LPWSTR lpSrc,DWORD dwSrc)
{
WCHAR szBuf[312];
if (ExpandEnvironmentStrings(lpSrc,szBuf,COUNTOF(szBuf)))
lstrcpyn(lpSrc,szBuf,dwSrc);
}
//=============================================================================
//
// PathCanonicalizeEx()
//
//
void PathCanonicalizeEx(LPWSTR lpSrc)
{
WCHAR szDst[MAX_PATH];
if (PathCanonicalize(szDst,lpSrc))
lstrcpy(lpSrc,szDst);
}
//=============================================================================
//
// GetLongPathNameEx()
//
// Works fine with Windows 95!
//
extern LPMALLOC g_lpMalloc;
DWORD GetLongPathNameEx(LPCWSTR lpszShortPath,LPWSTR lpszLongPath,DWORD cchBuffer)
{
WCHAR wszShortPath[MAX_PATH];
WCHAR *pwchSep;
LPSHELLFOLDER lpsfDesktop;
ULONG chParsed = 0;
ULONG dwAttributes = 0;
LPITEMIDLIST pidl = NULL;
BOOL fSucceeded = FALSE;
//MessageBox(GetFocus(),lpszShortPath,L"GetLongPathNameEx(): lpszShortPath",0);
// Convert lpszShortPath to a UNICODE string
/*MultiByteToWideChar(
CP_ACP,MB_PRECOMPOSED,lpszShortPath,-1,wszShortPath,MAX_PATH);*/
lstrcpy(wszShortPath,lpszShortPath);
// convert slashes to backlsashes
while (pwchSep = StrChr(wszShortPath,L'/'))
*pwchSep = L'\\';
// Get Desktop Folder
if (NOERROR == SHGetDesktopFolder(&lpsfDesktop))
{
// Convert wszShortPath to a pidl
if (NOERROR == lpsfDesktop->lpVtbl->ParseDisplayName(
lpsfDesktop,NULL,NULL,wszShortPath,&chParsed,&pidl,&dwAttributes))
{
if (SHGetPathFromIDList(pidl,lpszLongPath))
fSucceeded = FALSE;
g_lpMalloc->lpVtbl->Free(g_lpMalloc,pidl);
}
}
//MessageBox(GetFocus(),lpszLongPath,L"GetLongPathNameEx(): lpszLongPath",0);
if (fSucceeded)
return(lstrlen(lpszLongPath));
else {
if (lpszShortPath != lpszLongPath)
lstrcpy(lpszLongPath,lpszShortPath);
return(0);
}
cchBuffer;
}
//=============================================================================
//
// SHGetFileInfo2() - return a default name when the file has been removed
//
DWORD_PTR SHGetFileInfo2(LPCWSTR pszPath,DWORD dwFileAttributes,
SHFILEINFO *psfi,UINT cbFileInfo,UINT uFlags)
{
if (PathFileExists(pszPath))
return SHGetFileInfo(pszPath,dwFileAttributes,psfi,cbFileInfo,uFlags);
else
return SHGetFileInfo(pszPath,FILE_ATTRIBUTE_NORMAL,
psfi,cbFileInfo,uFlags|SHGFI_USEFILEATTRIBUTES);
}
//=============================================================================
//
// FormatNumberStr()
//
int FormatNumberStr(LPWSTR lpNumberStr)
{
WCHAR *c;
WCHAR szSep[8];
int i = 0;
if (!lstrlen(lpNumberStr))
return(0);
if (!GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_STHOUSAND,
szSep,
COUNTOF(szSep)))
szSep[0] = L'\'';
c = StrEnd(lpNumberStr);
while ((c = CharPrev(lpNumberStr,c)) != lpNumberStr)
{
if (++i == 3)
{
i = 0;
MoveMemory(c+1,c,sizeof(WCHAR)*(lstrlen(c)+1));
*c = szSep[0];
}
}
return(lstrlen(lpNumberStr));
}
//=============================================================================
//
// SetDlgItemIntEx()
//
BOOL SetDlgItemIntEx(HWND hwnd,int nIdItem,UINT uValue)
{
WCHAR szBuf[64];
wsprintf(szBuf,L"%u",uValue);
FormatNumberStr(szBuf);
return(SetDlgItemText(hwnd,nIdItem,szBuf));
}
//=============================================================================
//
// A2W: Convert Dialog Item Text form Unicode to UTF-8 and vice versa
//
UINT GetDlgItemTextA2W(UINT uCP,HWND hDlg,int nIDDlgItem,LPSTR lpString,int nMaxCount)
{
WCHAR wsz[1024] = L"";
UINT uRet = GetDlgItemTextW(hDlg,nIDDlgItem,wsz,COUNTOF(wsz));
ZeroMemory(lpString,nMaxCount);
WCharToMBCS(uCP,wsz,lpString,nMaxCount-2);
return uRet;
}
UINT SetDlgItemTextA2W(UINT uCP,HWND hDlg,int nIDDlgItem,LPSTR lpString)
{
WCHAR wsz[1024] = L"";
MBCSToWChar(uCP,lpString,wsz,COUNTOF(wsz));
return SetDlgItemTextW(hDlg,nIDDlgItem,wsz);
}
LRESULT ComboBox_AddStringA2W(UINT uCP,HWND hwnd,LPCSTR lpString)
{
WCHAR wsz[1024] = L"";
MBCSToWChar(uCP,lpString,wsz,COUNTOF(wsz));
return SendMessageW(hwnd,CB_ADDSTRING,0,(LPARAM)wsz);
}
//=============================================================================
//
// CodePageFromCharSet()
//
UINT CodePageFromCharSet(UINT uCharSet)
{
CHARSETINFO ci;
if (TranslateCharsetInfo((DWORD*)uCharSet,&ci,TCI_SRCCHARSET))
return(ci.ciACP);
else
return(GetACP());
}
//=============================================================================
//
// MRU functions
//
LPMRULIST MRU_Create(LPCWSTR pszRegKey,int iFlags,int iSize) {
LPMRULIST pmru = LocalAlloc(LPTR,sizeof(MRULIST));
ZeroMemory(pmru,sizeof(MRULIST));
lstrcpyn(pmru->szRegKey,pszRegKey,COUNTOF(pmru->szRegKey));
pmru->iFlags = iFlags;
pmru->iSize = min(iSize,MRU_MAXITEMS);
return(pmru);
}
BOOL MRU_Destroy(LPMRULIST pmru) {
int i;
for (i = 0; i < pmru->iSize; i++) {
if (pmru->pszItems[i])
LocalFree(pmru->pszItems[i]);
}
ZeroMemory(pmru,sizeof(MRULIST));
LocalFree(pmru);
return(1);
}
int MRU_Compare(LPMRULIST pmru,LPCWSTR psz1,LPCWSTR psz2) {
if (pmru->iFlags & MRU_NOCASE)
return(lstrcmpi(psz1,psz2));
else
return(lstrcmp(psz1,psz2));
}
BOOL MRU_Add(LPMRULIST pmru,LPCWSTR pszNew) {
int i;
for (i = 0; i < pmru->iSize; i++) {
if (MRU_Compare(pmru,pmru->pszItems[i],pszNew) == 0) {
LocalFree(pmru->pszItems[i]);
break;
}
}
i = min(i,pmru->iSize-1);
for (; i > 0; i--)
pmru->pszItems[i] = pmru->pszItems[i-1];
pmru->pszItems[0] = StrDup(pszNew);
return(1);
}
BOOL MRU_AddFile(LPMRULIST pmru,LPCWSTR pszFile,BOOL bRelativePath,BOOL bUnexpandMyDocs) {
int i;
for (i = 0; i < pmru->iSize; i++) {
if (lstrcmpi(pmru->pszItems[i],pszFile) == 0) {
LocalFree(pmru->pszItems[i]);
break;
}
else {
WCHAR wchItem[MAX_PATH];
PathAbsoluteFromApp(pmru->pszItems[i],wchItem,COUNTOF(wchItem),TRUE);
if (lstrcmpi(wchItem,pszFile) == 0) {
LocalFree(pmru->pszItems[i]);
break;
}
}
}
i = min(i,pmru->iSize-1);
for (; i > 0; i--)
pmru->pszItems[i] = pmru->pszItems[i-1];
if (bRelativePath) {
WCHAR wchFile[MAX_PATH];
PathRelativeToApp((LPWSTR)pszFile,wchFile,COUNTOF(wchFile),TRUE,TRUE,bUnexpandMyDocs);
pmru->pszItems[0] = StrDup(wchFile);
}
else
pmru->pszItems[0] = StrDup(pszFile);
// Needed to make W7 jump lists work when NP2 is not explicitly associated
if (IsW7()) SHAddToRecentDocs(SHARD_PATHW, pszFile);
return(1);
}
BOOL MRU_Delete(LPMRULIST pmru,int iIndex) {
int i;
if (iIndex < 0 || iIndex > pmru->iSize-1)
return(0);
if (pmru->pszItems[iIndex])
LocalFree(pmru->pszItems[iIndex]);
for (i = iIndex; i < pmru->iSize-1; i++) {
pmru->pszItems[i] = pmru->pszItems[i+1];
pmru->pszItems[i+1] = NULL;
}
return(1);
}
BOOL MRU_DeleteFileFromStore(LPMRULIST pmru,LPCWSTR pszFile) {
int i = 0;
LPMRULIST pmruStore;
WCHAR wchItem[256];
pmruStore = MRU_Create(pmru->szRegKey,pmru->iFlags,pmru->iSize);
MRU_Load(pmruStore);
while (MRU_Enum(pmruStore,i,wchItem,COUNTOF(wchItem)) != -1) {
PathAbsoluteFromApp(wchItem,wchItem,COUNTOF(wchItem),TRUE);
if (lstrcmpi(wchItem,pszFile) == 0)
MRU_Delete(pmruStore,i);
else
i++;
}
MRU_Save(pmruStore);
MRU_Destroy(pmruStore);
return(1);
}
BOOL MRU_Empty(LPMRULIST pmru) {
int i;
for (i = 0; i < pmru->iSize; i++) {
if (pmru->pszItems[i]) {
LocalFree(pmru->pszItems[i]);
pmru->pszItems[i] = NULL;
}
}
return(1);
}
int MRU_Enum(LPMRULIST pmru,int iIndex,LPWSTR pszItem,int cchItem) {
if (pszItem == NULL || cchItem == 0) {
int i = 0;
while (pmru->pszItems[i] && i < pmru->iSize)
i++;
return(i);
}
else {
if (iIndex < 0 || iIndex > pmru->iSize-1 || !pmru->pszItems[iIndex])
return(-1);
else {
lstrcpyn(pszItem,pmru->pszItems[iIndex],cchItem);
return(lstrlen(pszItem));
}
}
}
BOOL MRU_Load(LPMRULIST pmru) {
int i,n = 0;
WCHAR tchName[32];
WCHAR tchItem[1024];
WCHAR *pIniSection = LocalAlloc(LPTR,sizeof(WCHAR)*32*1024);
MRU_Empty(pmru);
LoadIniSection(pmru->szRegKey,pIniSection,LocalSize(pIniSection)/sizeof(WCHAR));
for (i = 0; i < pmru->iSize; i++) {
wsprintf(tchName,L"%.2i",i+1);
if (IniSectionGetString(pIniSection,tchName,L"",tchItem,COUNTOF(tchItem))) {
/*if (pmru->iFlags & MRU_UTF8) {
WCHAR wchItem[1024];
int cbw = MultiByteToWideChar(CP_UTF7,0,tchItem,-1,wchItem,COUNTOF(wchItem));
WideCharToMultiByte(CP_UTF8,0,wchItem,cbw,tchItem,COUNTOF(tchItem),NULL,NULL);
pmru->pszItems[n++] = StrDup(tchItem);
}
else*/
pmru->pszItems[n++] = StrDup(tchItem);
}
}
LocalFree(pIniSection);
return(1);
}
BOOL MRU_Save(LPMRULIST pmru) {
int i;
WCHAR tchName[32];
WCHAR *pIniSection = LocalAlloc(LPTR,sizeof(WCHAR)*32*1024);
//IniDeleteSection(pmru->szRegKey);
for (i = 0; i < pmru->iSize; i++) {
if (pmru->pszItems[i]) {
wsprintf(tchName,L"%.2i",i+1);
/*if (pmru->iFlags & MRU_UTF8) {
WCHAR tchItem[1024];
WCHAR wchItem[1024];
int cbw = MultiByteToWideChar(CP_UTF8,0,pmru->pszItems[i],-1,wchItem,COUNTOF(wchItem));
WideCharToMultiByte(CP_UTF7,0,wchItem,cbw,tchItem,COUNTOF(tchItem),NULL,NULL);
IniSectionSetString(pIniSection,tchName,tchItem);
}
else*/
IniSectionSetString(pIniSection,tchName,pmru->pszItems[i]);
}
}
SaveIniSection(pmru->szRegKey,pIniSection);
LocalFree(pIniSection);
return(1);
}
BOOL MRU_MergeSave(LPMRULIST pmru,BOOL bAddFiles,BOOL bRelativePath,BOOL bUnexpandMyDocs) {
int i;
LPMRULIST pmruBase;
pmruBase = MRU_Create(pmru->szRegKey,pmru->iFlags,pmru->iSize);
MRU_Load(pmruBase);
if (bAddFiles) {
for (i = pmru->iSize-1; i >= 0; i--) {
if (pmru->pszItems[i]) {
WCHAR wchItem[MAX_PATH];
PathAbsoluteFromApp(pmru->pszItems[i],wchItem,COUNTOF(wchItem),TRUE);
MRU_AddFile(pmruBase,wchItem,bRelativePath,bUnexpandMyDocs);
}
}
}
else {
for (i = pmru->iSize-1; i >= 0; i--) {
if (pmru->pszItems[i])
MRU_Add(pmruBase,pmru->pszItems[i]);
}
}
MRU_Save(pmruBase);
MRU_Destroy(pmruBase);
return(1);
}
/*
Themed Dialogs
Modify dialog templates to use current theme font
Based on code of MFC helper class CDialogTemplate
*/
BOOL GetThemedDialogFont(LPWSTR lpFaceName,WORD* wSize)
{
HDC hDC;
int iLogPixelsY;
HMODULE hModUxTheme;
HTHEME hTheme;
LOGFONT lf;
BOOL bSucceed = FALSE;
hDC = GetDC(NULL);
iLogPixelsY = GetDeviceCaps(hDC,LOGPIXELSY);
ReleaseDC(NULL,hDC);
if (hModUxTheme = GetModuleHandle(L"uxtheme.dll")) {
if ((BOOL)(GetProcAddress(hModUxTheme,"IsAppThemed"))()) {
hTheme = (HTHEME)(GetProcAddress(hModUxTheme,"OpenThemeData"))(NULL,L"WINDOWSTYLE;WINDOW");
if (hTheme) {
if (S_OK == (HRESULT)(GetProcAddress(hModUxTheme,"GetThemeSysFont"))(hTheme,/*TMT_MSGBOXFONT*/805,&lf)) {
if (lf.lfHeight < 0)
lf.lfHeight = -lf.lfHeight;
*wSize = (WORD)MulDiv(lf.lfHeight,72,iLogPixelsY);
if (*wSize == 0)
*wSize = 8;
StrCpyN(lpFaceName,lf.lfFaceName,LF_FACESIZE);
bSucceed = TRUE;
}
(GetProcAddress(hModUxTheme,"CloseThemeData"))(hTheme);
}
}
}
/*
if (!bSucceed) {
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&ncm,0);
if (ncm.lfMessageFont.lfHeight < 0)
ncm.lfMessageFont.lfHeight = -ncm.lfMessageFont.lfHeight;
*wSize = (WORD)MulDiv(ncm.lfMessageFont.lfHeight,72,iLogPixelsY);
if (*wSize == 0)
*wSize = 8;
StrCpyN(lpFaceName,ncm.lfMessageFont.lfFaceName,LF_FACESIZE);
}*/
return(bSucceed);
}
__inline BOOL DialogTemplate_IsDialogEx(const DLGTEMPLATE* pTemplate) {
return ((DLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF;
}
__inline BOOL DialogTemplate_HasFont(const DLGTEMPLATE* pTemplate) {
return (DS_SETFONT &
(DialogTemplate_IsDialogEx(pTemplate) ? ((DLGTEMPLATEEX*)pTemplate)->style : pTemplate->style));
}
__inline int DialogTemplate_FontAttrSize(BOOL bDialogEx) {
return (int)sizeof(WORD) * (bDialogEx ? 3 : 1);
}
__inline BYTE* DialogTemplate_GetFontSizeField(const DLGTEMPLATE* pTemplate) {
BOOL bDialogEx = DialogTemplate_IsDialogEx(pTemplate);
WORD* pw;
if (bDialogEx)
pw = (WORD*)((DLGTEMPLATEEX*)pTemplate + 1);
else
pw = (WORD*)(pTemplate + 1);
if (*pw == (WORD)-1)
pw += 2;
else
while(*pw++);
if (*pw == (WORD)-1)
pw += 2;
else
while(*pw++);
while (*pw++);
return (BYTE*)pw;
}
DLGTEMPLATE* LoadThemedDialogTemplate(LPCTSTR lpDialogTemplateID,HINSTANCE hInstance) {
HRSRC hRsrc;
HGLOBAL hRsrcMem;
DLGTEMPLATE *pRsrcMem;
DLGTEMPLATE *pTemplate;
UINT dwTemplateSize = 0;
WCHAR wchFaceName[LF_FACESIZE];
WORD wFontSize;
BOOL bDialogEx;
BOOL bHasFont;
int cbFontAttr;
int cbNew;
int cbOld;
BYTE* pbNew;
BYTE* pb;
BYTE* pOldControls;
BYTE* pNewControls;
WORD nCtrl;
hRsrc = FindResource(hInstance,lpDialogTemplateID,RT_DIALOG);
if (hRsrc == NULL)
return(NULL);
hRsrcMem = LoadResource(hInstance,hRsrc);
pRsrcMem = (DLGTEMPLATE*)LockResource(hRsrcMem);
dwTemplateSize = (UINT)SizeofResource(hInstance,hRsrc);
if ((dwTemplateSize == 0) ||
(pTemplate = LocalAlloc(LPTR,dwTemplateSize+LF_FACESIZE*2)) == NULL) {
UnlockResource(hRsrcMem);
FreeResource(hRsrcMem);
return(NULL);
}
CopyMemory((BYTE*)pTemplate,pRsrcMem,(size_t)dwTemplateSize);
UnlockResource(hRsrcMem);
FreeResource(hRsrcMem);
if (!GetThemedDialogFont(wchFaceName,&wFontSize))
return(pTemplate);
bDialogEx = DialogTemplate_IsDialogEx(pTemplate);
bHasFont = DialogTemplate_HasFont(pTemplate);
cbFontAttr = DialogTemplate_FontAttrSize(bDialogEx);
if (bDialogEx)
((DLGTEMPLATEEX*)pTemplate)->style |= DS_SHELLFONT;
else
pTemplate->style |= DS_SHELLFONT;
cbNew = cbFontAttr + ((lstrlen(wchFaceName) + 1) * sizeof(WCHAR));
pbNew = (BYTE*)wchFaceName;
pb = DialogTemplate_GetFontSizeField(pTemplate);
cbOld = (int)(bHasFont ? cbFontAttr + 2 * (lstrlen((WCHAR*)(pb + cbFontAttr)) + 1) : 0);
pOldControls = (BYTE*)(((DWORD_PTR)pb + cbOld + 3) & ~(DWORD_PTR)3);
pNewControls = (BYTE*)(((DWORD_PTR)pb + cbNew + 3) & ~(DWORD_PTR)3);
nCtrl = bDialogEx ?
(WORD)((DLGTEMPLATEEX*)pTemplate)->cDlgItems :
(WORD)pTemplate->cdit;
if (cbNew != cbOld && nCtrl > 0)
MoveMemory(pNewControls,pOldControls,(size_t)(dwTemplateSize - (pOldControls - (BYTE*)pTemplate)));
*(WORD*)pb = wFontSize;
MoveMemory(pb + cbFontAttr,pbNew,(size_t)(cbNew - cbFontAttr));
return(pTemplate);
}
INT_PTR ThemedDialogBoxParam(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM dwInitParam) {
INT ret;
DLGTEMPLATE *pDlgTemplate;
pDlgTemplate = LoadThemedDialogTemplate(lpTemplate,hInstance);
ret = DialogBoxIndirectParam(hInstance,pDlgTemplate,hWndParent,lpDialogFunc,dwInitParam);
if (pDlgTemplate)
LocalFree(pDlgTemplate);
return(ret);
}
HWND CreateThemedDialogParam(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM dwInitParam) {
HWND hwnd;
DLGTEMPLATE *pDlgTemplate;
pDlgTemplate = LoadThemedDialogTemplate(lpTemplate,hInstance);
hwnd = CreateDialogIndirectParam(hInstance,pDlgTemplate,hWndParent,lpDialogFunc,dwInitParam);
if (pDlgTemplate)
LocalFree(pDlgTemplate);
return(hwnd);
}
/******************************************************************************
*
* UnSlash functions
* Mostly taken from SciTE, (c) Neil Hodgson, http://www.scintilla.org
*
/
/**
* Is the character an octal digit?
*/
static BOOL IsOctalDigit(char ch) {
return ch >= '0' && ch <= '7';
}
/**
* If the character is an hexa digit, get its value.
*/
static int GetHexaDigit(char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
}
if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
}
return -1;
}
/**
* Convert C style \a, \b, \f, \n, \r, \t, \v, \ooo and \xhh into their indicated characters.
*/
unsigned int UnSlash(char *s) {
char *sStart = s;
char *o = s;
while (*s) {
if (*s == '\\') {
s++;
if (*s == 'a') {
*o = '\a';
} else if (*s == 'b') {
*o = '\b';
} else if (*s == 'f') {
*o = '\f';
} else if (*s == 'n') {
*o = '\n';
} else if (*s == 'r') {
*o = '\r';
} else if (*s == 't') {
*o = '\t';
} else if (*s == 'v') {
*o = '\v';
} else if (IsOctalDigit(*s)) {
int val = *s - '0';
if (IsOctalDigit(*(s + 1))) {
s++;
val *= 8;
val += *s - '0';
if (IsOctalDigit(*(s + 1))) {
s++;
val *= 8;
val += *s - '0';
}
}
*o = (char)(val);
} else if (*s == 'x') {
int val, ghd;
s++;
val = 0;
ghd = GetHexaDigit(*s);
if (ghd >= 0) {
s++;
val = ghd;
ghd = GetHexaDigit(*s);
if (ghd >= 0) {
s++;
val *= 16;
val += ghd;
}
}
*o = (char)(val);
} else {
*o = *s;
}
} else {
*o = *s;
}
o++;
if (*s) {
s++;
}
}
*o = '\0';
return o - sStart;
}
/**
* Convert C style \0oo into their indicated characters.
* This is used to get control characters into the regular expresion engine.
*/
unsigned int UnSlashLowOctal(char *s) {
char *sStart = s;
char *o = s;
while (*s) {
if ((s[0] == '\\') && (s[1] == '0') && IsOctalDigit(s[2]) && IsOctalDigit(s[3])) {
*o = (char)(8 * (s[2] - '0') + (s[3] - '0'));
s += 3;
} else {
*o = *s;
}
o++;
if (*s)
s++;
}
*o = '\0';
return o - sStart;
}
void TransformBackslashes(char* pszInput,BOOL bRegEx)
{
if (bRegEx)
UnSlashLowOctal(pszInput);
else
UnSlash(pszInput);
}
/*
MinimizeToTray - Copyright 2000 Matthew Ellis <m.t.ellis@bigfoot.com>
Changes made by flo:
- Commented out: #include "stdafx.h"
- Moved variable declaration: APPBARDATA appBarData;
*/
// MinimizeToTray
//
// A couple of routines to show how to make it produce a custom caption
// animation to make it look like we are minimizing to and maximizing
// from the system tray
//
// These routines are public domain, but it would be nice if you dropped
// me a line if you use them!
//
// 1.0 29.06.2000 Initial version
// 1.1 01.07.2000 The window retains it's place in the Z-order of windows
// when minimized/hidden. This means that when restored/shown, it doen't
// always appear as the foreground window unless we call SetForegroundWindow
//
// Copyright 2000 Matthew Ellis <m.t.ellis@bigfoot.com>
/*#include "stdafx.h"*/
// Odd. VC++6 winuser.h has IDANI_CAPTION defined (as well as IDANI_OPEN and
// IDANI_CLOSE), but the Platform SDK only has IDANI_OPEN...
// I don't know what IDANI_OPEN or IDANI_CLOSE do. Trying them in this code
// produces nothing. Perhaps they were intended for window opening and closing
// like the MAC provides...
#ifndef IDANI_OPEN
#define IDANI_OPEN 1
#endif
#ifndef IDANI_CLOSE
#define IDANI_CLOSE 2
#endif
#ifndef IDANI_CAPTION
#define IDANI_CAPTION 3
#endif
#define DEFAULT_RECT_WIDTH 150
#define DEFAULT_RECT_HEIGHT 30
// Returns the rect of where we think the system tray is. This will work for
// all current versions of the shell. If explorer isn't running, we try our
// best to work with a 3rd party shell. If we still can't find anything, we
// return a rect in the lower right hand corner of the screen
static VOID GetTrayWndRect(LPRECT lpTrayRect)
{
APPBARDATA appBarData;
// First, we'll use a quick hack method. We know that the taskbar is a window
// of class Shell_TrayWnd, and the status tray is a child of this of class
// TrayNotifyWnd. This provides us a window rect to minimize to. Note, however,
// that this is not guaranteed to work on future versions of the shell. If we
// use this method, make sure we have a backup!
HWND hShellTrayWnd=FindWindowEx(NULL,NULL,TEXT("Shell_TrayWnd"),NULL);
if(hShellTrayWnd)
{
HWND hTrayNotifyWnd=FindWindowEx(hShellTrayWnd,NULL,TEXT("TrayNotifyWnd"),NULL);
if(hTrayNotifyWnd)
{
GetWindowRect(hTrayNotifyWnd,lpTrayRect);
return;
}
}
// OK, we failed to get the rect from the quick hack. Either explorer isn't
// running or it's a new version of the shell with the window class names
// changed (how dare Microsoft change these undocumented class names!) So, we
// try to find out what side of the screen the taskbar is connected to. We
// know that the system tray is either on the right or the bottom of the
// taskbar, so we can make a good guess at where to minimize to
/*APPBARDATA appBarData;*/
appBarData.cbSize=sizeof(appBarData);
if(SHAppBarMessage(ABM_GETTASKBARPOS,&appBarData))
{
// We know the edge the taskbar is connected to, so guess the rect of the
// system tray. Use various fudge factor to make it look good
switch(appBarData.uEdge)
{
case ABE_LEFT:
case ABE_RIGHT:
// We want to minimize to the bottom of the taskbar
lpTrayRect->top=appBarData.rc.bottom-100;
lpTrayRect->bottom=appBarData.rc.bottom-16;
lpTrayRect->left=appBarData.rc.left;
lpTrayRect->right=appBarData.rc.right;
break;
case ABE_TOP:
case ABE_BOTTOM:
// We want to minimize to the right of the taskbar
lpTrayRect->top=appBarData.rc.top;
lpTrayRect->bottom=appBarData.rc.bottom;
lpTrayRect->left=appBarData.rc.right-100;
lpTrayRect->right=appBarData.rc.right-16;
break;
}
return;
}
// Blimey, we really aren't in luck. It's possible that a third party shell
// is running instead of explorer. This shell might provide support for the
// system tray, by providing a Shell_TrayWnd window (which receives the
// messages for the icons) So, look for a Shell_TrayWnd window and work out
// the rect from that. Remember that explorer's taskbar is the Shell_TrayWnd,
// and stretches either the width or the height of the screen. We can't rely
// on the 3rd party shell's Shell_TrayWnd doing the same, in fact, we can't
// rely on it being any size. The best we can do is just blindly use the
// window rect, perhaps limiting the width and height to, say 150 square.
// Note that if the 3rd party shell supports the same configuraion as
// explorer (the icons hosted in NotifyTrayWnd, which is a child window of
// Shell_TrayWnd), we would already have caught it above
hShellTrayWnd=FindWindowEx(NULL,NULL,TEXT("Shell_TrayWnd"),NULL);
if(hShellTrayWnd)
{
GetWindowRect(hShellTrayWnd,lpTrayRect);
if(lpTrayRect->right-lpTrayRect->left>DEFAULT_RECT_WIDTH)
lpTrayRect->left=lpTrayRect->right-DEFAULT_RECT_WIDTH;
if(lpTrayRect->bottom-lpTrayRect->top>DEFAULT_RECT_HEIGHT)
lpTrayRect->top=lpTrayRect->bottom-DEFAULT_RECT_HEIGHT;
return;
}
// OK. Haven't found a thing. Provide a default rect based on the current work
// area
SystemParametersInfo(SPI_GETWORKAREA,0,lpTrayRect,0);
lpTrayRect->left=lpTrayRect->right-DEFAULT_RECT_WIDTH;
lpTrayRect->top=lpTrayRect->bottom-DEFAULT_RECT_HEIGHT;
}
// Check to see if the animation has been disabled
static BOOL GetDoAnimateMinimize(VOID)
{
ANIMATIONINFO ai;
ai.cbSize=sizeof(ai);
SystemParametersInfo(SPI_GETANIMATION,sizeof(ai),&ai,0);
return ai.iMinAnimate?TRUE:FALSE;
}
VOID MinimizeWndToTray(HWND hWnd)
{
if(GetDoAnimateMinimize())
{
RECT rcFrom,rcTo;
// Get the rect of the window. It is safe to use the rect of the whole
// window - DrawAnimatedRects will only draw the caption
GetWindowRect(hWnd,&rcFrom);
GetTrayWndRect(&rcTo);
// Get the system to draw our animation for us
DrawAnimatedRects(hWnd,IDANI_CAPTION,&rcFrom,&rcTo);
}
// Add the tray icon. If we add it before the call to DrawAnimatedRects,
// the taskbar gets erased, but doesn't get redrawn until DAR finishes.
// This looks untidy, so call the functions in this order
// Hide the window
ShowWindow(hWnd,SW_HIDE);
}
VOID RestoreWndFromTray(HWND hWnd)
{
if(GetDoAnimateMinimize())
{
// Get the rect of the tray and the window. Note that the window rect
// is still valid even though the window is hidden
RECT rcFrom,rcTo;
GetTrayWndRect(&rcFrom);
GetWindowRect(hWnd,&rcTo);
// Get the system to draw our animation for us
DrawAnimatedRects(hWnd,IDANI_CAPTION,&rcFrom,&rcTo);
}
// Show the window, and make sure we're the foreground window
ShowWindow(hWnd,SW_SHOW);
SetActiveWindow(hWnd);
SetForegroundWindow(hWnd);
// Remove the tray icon. As described above, remove the icon after the
// call to DrawAnimatedRects, or the taskbar will not refresh itself
// properly until DAR finished
}
/// End of Helpers.c \\\
Jump to Line
Something went wrong with that request. Please try again.