Added string lookup tool

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7251 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2021-01-17 20:57:20 +00:00
parent 79df77fa82
commit 60ab777e21
10 changed files with 426 additions and 43 deletions

View file

@ -211,7 +211,8 @@ Version History
2.3.6
- Added GUID generator tool
2.3.7
2.4
- Added Lookup tool
- Use Consolas font if it exists
Copyright Information

View file

@ -6,6 +6,7 @@ files = Split("""
utils.cpp
version.cpp
update.cpp
lookup.cpp
wndspy.cpp
""")
@ -42,6 +43,7 @@ libs = Split("""
wininet
winmm
kernel32
ole32
""")
docs = Split("""
@ -58,7 +60,7 @@ BuildUtil(
res = res,
resources = resources,
entry = None,
defines = ['RELEASE=2.3.7'],
defines = ['RELEASE=2.4'],
docs = docs,
root_util = True
)

View file

@ -0,0 +1,324 @@
// Copyright (C) 2020-2021 Anders Kjersem
//
// This file is a part of NSIS.
//
// Licensed under the zlib/libpng license (the "License");
// you may not use this file except in compliance with the License.
//
// Licence details can be found in the file COPYING.
//
// This software is provided 'as-is', without any express or implied
// warranty.
#include "makensisw.h"
#include <windows.h>
#include <windowsx.h>
#include <Shlobj.h>
#include <shlwapi.h>
#include "utils.h"
#include "resource.h"
enum { reg_mui_string_truncate = 0x01 };
static void StrTToW(LPCTSTR Src, LPWSTR Dst, UINT cch)
{
if (sizeof(*Src) == sizeof(*Dst))
lstrcpynW(Dst, (LPCWSTR) Src, cch);
else
MultiByteToWideChar(CP_ACP, 0, (LPCSTR) Src, -1, Dst, cch);
}
template<class T> static LPWSTR SmartStrTToW(T*Src, LPWSTR Dst, UINT cch)
{
if (sizeof(T) == sizeof(*Dst)) return (LPWSTR) Src;
return (StrTToW(Src, Dst, cch), Dst);
}
template<class T> static int WINAPI StrBase10ToSInt(const T*str)
{
unsigned int v = 0, neg = 0, c, i = 0, base = 10;
if (str[i] == '-') ++neg, ++i;
for (; (c = str[i]) >= T('0') && c <= T('9'); ++i) c -= T('0'), v *= base, v += c;
return neg ? (int) v * -1 : v;
}
template<class T> static int WINAPI PathParseIconLocationFallback(T*Path)
{
int idx = 0;
SIZE_T i, comma = 0;
for (i = 0; Path[i]; ++i)
{
if (Path[i] == ',') comma = i;
if (FSPath::IsAgnosticSeparator(Path[i])) comma = 0;
}
if (comma)
{
Path[comma] = T('\0');
idx = StrBase10ToSInt(Path + comma + 1);
}
return idx;
}
static HRESULT GetSpecialFolderPath(HWND hWnd, LPTSTR Buf, UINT csidl)
{
UINT create = csidl & CSIDL_FLAG_CREATE, succ, ec;
csidl &= ~CSIDL_FLAG_CREATE;
if (SupportsWNT4() || SupportsW95())
{
LPITEMIDLIST pidl;
HRESULT hr = SHGetSpecialFolderLocation(hWnd, csidl, &pidl);
if (SUCCEEDED(hr))
{
hr = SHGetPathFromIDList(pidl, Buf) ? S_OK : E_FAIL, CoTaskMemFree(pidl);
if (SUCCEEDED(hr) && create)
{
succ = CreateDirectory(Buf, NULL);
hr = (succ || (ec = GetLastError()) == ERROR_ALREADY_EXISTS) ? S_OK : HRESULT_FROM_WIN32(ec);
}
}
return hr;
}
succ = SHGetSpecialFolderPath(hWnd, Buf, csidl, false);
if (!succ && create) succ = SHGetSpecialFolderPath(hWnd, Buf, csidl, create);
return succ ? S_OK : E_FAIL;
}
static HICON LoadIconFromLocation(LPCTSTR Path, int Idx)
{
// web.archive.org/web/201901/https://blogs.msdn.microsoft.com/oldnewthing/20100505-00/?p=14153# -1 is special
HICON hIco = ExtractIcon(NULL, Path, Idx == -1 ? 0 : Idx);
if (!hIco && !GetLastError()) SetLastError(ERROR_NOT_FOUND);
return hIco;
}
template<class T> static void AppendText(HWND hEdit, const T*Str)
{
SNDMSG(hEdit, EM_SETSEL, 0, -1), SNDMSG(hEdit, EM_SETSEL, -1, -1);
if (sizeof(T) > 1)
SendMessageW(hEdit, EM_REPLACESEL, 0, (SIZE_T) Str);
else
SendMessageA(hEdit, EM_REPLACESEL, 0, (SIZE_T) Str);
}
static int AddComboStringWithData(HWND hWnd, LPCSTR Str, SIZE_T Data)
{
int idx = (int) SendMessageA(hWnd, CB_INSERTSTRING, (INT_PTR) -1, (SIZE_T) const_cast<LPCSTR>(Str));
if (idx >= 0) SendMessage(hWnd, CB_SETITEMDATA, idx, Data);
return idx;
}
template<class I, class O> static HKEY ParseRegPath(I*In, O*&Path, O*&Name)
{
HKEY hKey = GetRegRootKey(In);
I*pp = 0, *pn = 0;
if (hKey)
{
SIZE_T i;
for (i = 0; In[i]; ++i)
if (In[i] == I('\\'))
(!pp ? pp : pn) = &In[i + 1]; // First separator after HK* or last separator
if (pn) pn[-1] = I('\0'); // Split path and name
}
return (Path = const_cast<O*>(pp), Name = const_cast<O*>(pn), hKey);
}
HRESULT (WINAPI*g_SHLIS)(LPCWSTR s, LPWSTR o, UINT cch, PVOID*ppvReserved);
HRESULT (WINAPI*g_RLMSOld)(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf);
static LSTATUS WINAPI RegLoadMUIStringFallbackW(HKEY hKey, LPCWSTR Name, LPWSTR Out, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory)
{
if ((Flags & reg_mui_string_truncate) && pcbData) return ERROR_INVALID_PARAMETER;
if (g_RLMSOld)
{
HRESULT hr = g_RLMSOld(hKey, Name, Out, cbOutBuf);
if (SUCCEEDED(hr))
{
if (pcbData) *pcbData = (StrLenT(Out) + 1) * sizeof(*Out);
return ERROR_SUCCESS;
}
if (pcbData) *pcbData = (cbOutBuf|1) * 2; // We have no real value to set, caller just has to loop until success
return hr; // Note: Not converting E_* here, FormatMessage knows what to do.
}
return ERROR_NOT_SUPPORTED;
}
enum { LM_SHGLN, LM_SHLIS, LM_RLMS, LM_PPIL };
LPCSTR g_ModeLbl[] = { "Path:", "Path:", "Registry:", "Path:" };
struct DIALOGDATA {
HRESULT (WINAPI*SHGLN)(PCWSTR p, PWSTR m, UINT cch, int*rid);
LSTATUS (WINAPI*RLMS)(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory);
int (WINAPI*PPIL)(LPTSTR p);
void*OrgParentDlgData;
HWND hMode, hExtra, hOutTxt, hOutIco;
DIALOGDATA() { extern void* g_ModalDlgData; OrgParentDlgData = g_ModalDlgData, g_ModalDlgData = this; }
~DIALOGDATA() { extern void* g_ModalDlgData; g_ModalDlgData = OrgParentDlgData; }
static DIALOGDATA* Get(HWND hDlg) { return (DIALOGDATA*) g_ModalDlgData; }
static inline void Set(HWND hDlg, DIALOGDATA*p) { }
};
static INT_PTR CALLBACK LookupDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM LParam)
{
DIALOGDATA*pDD = DIALOGDATA::Get(hDlg);
int idx = pDD ? (int) SendMessage(pDD->hMode, CB_GETCURSEL, 0, 0) : 0;
UINT mode = pDD ? (UINT) SendMessage(pDD->hMode, CB_GETITEMDATA, idx, 0) : 0;
HRESULT hr;
TCHAR buf[MAX_PATH + 1 + 6]; // Path + ',' + resid
switch(Msg)
{
case WM_INITDIALOG:
DIALOGDATA::Set(hDlg, (pDD = (DIALOGDATA*) LParam));
CenterOnParent(hDlg);
pDD->hMode = GetDlgItem(hDlg, IDC_LUMODE);
pDD->hExtra = GetDlgItem(hDlg, IDC_LUEXTRATEXT);
pDD->hOutTxt = GetDlgItem(hDlg, IDC_LUOUTPUTTEXT);
pDD->hOutIco = CreateWindowEx(WS_EX_TRANSPARENT, _T("STATIC"), 0, WS_CHILD|WS_VISIBLE|SS_ICON|SS_CENTERIMAGE|SS_REALSIZECONTROL, 0, 0, 0, 0, pDD->hOutTxt, 0, 0, 0);
if (pDD->SHGLN) AddComboStringWithData(pDD->hMode, "SHGetLocalizedName", LM_SHGLN);
if (g_SHLIS) AddComboStringWithData(pDD->hMode, "SHLoadIndirectString", LM_SHLIS);
if (pDD->RLMS) AddComboStringWithData(pDD->hMode, "RegLoadMUIString", LM_RLMS);
if (pDD->PPIL) AddComboStringWithData(pDD->hMode, "PathParseIconLocation", LM_PPIL);
SNDMSG(pDD->hExtra, EM_LIMITTEXT, COUNTOF(buf), 0);
SNDMSG(pDD->hMode, CB_SETCURSEL, (SIZE_T) 0, 0), SNDMSG(hDlg, WM_COMMAND, MAKELONG(IDC_LUMODE, CBN_SELENDOK), (SIZE_T) pDD->hMode);
return TRUE;
case WM_CLOSE: close:
return EndDialog(hDlg, 0);
case WM_DESTROY:
{
HICON hOld = (HICON) SNDMSG(pDD->hOutIco, STM_SETICON, (SIZE_T) NULL, 0);
if (hOld) DestroyIcon(hOld);
}
break;
case WM_COMMAND:
switch((UINT) WParam)
{
case IDCANCEL:
goto close;
case MAKELONG(IDC_LUMODE, CBN_SELENDOK):
{
SendMessageA(GetDlgItem(hDlg, IDC_LUEXTRALABEL), WM_SETTEXT, 0, (SIZE_T) const_cast<LPCSTR>(g_ModeLbl[mode]));
LPCTSTR extra = buf;
*buf = '\0';
switch(mode)
{
case LM_SHGLN:
GetSpecialFolderPath(NULL, buf, CSIDL_COMMON_DESKTOPDIRECTORY);
break;
case LM_SHLIS:
extra = _T("@shell32,-4097");
break;
case LM_RLMS:
extra = _T("HKCR\\AudioCD\\shell\\play\\MUIVerb");
break;
case LM_PPIL:
extra = _T("%WINDIR%\\Explorer.exe,-101");
break;
}
ShowWindow(pDD->hOutIco, SW_HIDE);
SetWindowText(pDD->hExtra, extra);
}
break;
case MAKELONG(IDC_LUEXTRATEXT, EN_UPDATE):
SendMessage(pDD->hExtra, WM_GETTEXT, COUNTOF(buf), (SIZE_T) buf);
SetWindowText(pDD->hOutTxt, _T(""));
switch(mode)
{
case LM_SHGLN:
{
int resid;
WCHAR path[COUNTOF(buf)], mod[MAX_PATH], *pis;
pis = SmartStrTToW(buf, path, COUNTOF(path));
hr = pDD->SHGLN(pis, mod, COUNTOF(mod), &resid);
if (SUCCEEDED(hr))
{
AppendText(pDD->hOutTxt, mod);
AppendText(pDD->hOutTxt, (wsprintfW(path, L",%d\r\n\r\n", resid), path));
if (ExpandEnvironmentStringsW(mod, path, ARRAYSIZE(path)))
{
if (HMODULE hMod = LoadLibraryExW(path, NULL, LOAD_LIBRARY_AS_DATAFILE))
{
if (LoadStringW(hMod, resid, mod, ARRAYSIZE(mod)))
{
AppendText(pDD->hOutTxt, mod);
}
FreeLibrary(hMod);
}
}
}
else die_hr:
{
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, buf, COUNTOF(buf), NULL);
AppendText(pDD->hOutTxt, (wsprintfW(path, L"%#x: ", hr), path));
AppendText(pDD->hOutTxt, buf);
}
}
break;
case LM_SHLIS:
{
WCHAR is[COUNTOF(buf)], os[MAX_PATH], *pis;
pis = SmartStrTToW(buf, is, COUNTOF(is));
hr = g_SHLIS(pis, os, COUNTOF(os), NULL);
if (FAILED(hr)) goto die_hr;
AppendText(pDD->hOutTxt, os);
}
break;
case LM_RLMS:
{
UINT ec;
TCHAR *pkey, *pname;
if (HKEY hKey = ParseRegPath(buf, pkey, pname))
{
if (!(ec = RegOpenKeyForReading(hKey, pkey, &hKey)))
{
WCHAR namebuf[255+!0], outbuf[MAX_PATH], *pwn = SmartStrTToW(pname, namebuf, COUNTOF(namebuf));
ec = pDD->RLMS(hKey, pwn, outbuf, sizeof(outbuf), NULL, reg_mui_string_truncate, NULL);
if (!ec) AppendText(pDD->hOutTxt, outbuf);
RegCloseKey(hKey);
}
if (FAILED(hr = HRESULT_FROM_WIN32(ec))) goto die_hr;
}
}
break;
case LM_PPIL:
{
RECT r;
int idx = pDD->PPIL(buf);
HICON hIco = LoadIconFromLocation(buf, idx), hOld;
hr = GetLastError();
GetClientRect(pDD->hOutTxt, &r);
SetWindowPos(pDD->hOutIco, HWND_TOP, 0, 0, r.right, r.bottom, SWP_NOACTIVATE|(hIco ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
hOld = (HICON) SNDMSG(pDD->hOutIco, STM_SETICON, (SIZE_T) hIco, 0);
if (hOld) DestroyIcon(hOld);
if (!hIco) goto die_hr;
}
break;
}
break;
}
break;
}
return FALSE;
}
INT_PTR ShowLookupDialog(HWND hOwner)
{
DIALOGDATA dd;
(FARPROC&) dd.SHGLN = GetSysProcAddr("SHELL32", "SHGetLocalizedName");
(FARPROC&) g_SHLIS = GetSysProcAddr("SHLWAPI", (LPCSTR) 487);
(FARPROC&) dd.RLMS = GetSysProcAddr("ADVAPI32", "RegLoadMUIStringW"); // Note: RegLoadMUIStringA always returns ERROR_CALL_NOT_IMPLEMENTED
if (!dd.RLMS && ((FARPROC&) g_RLMSOld = GetSysProcAddr("SHLWAPI", (LPCSTR) 439))) dd.RLMS = RegLoadMUIStringFallbackW;
(FARPROC&) dd.PPIL =
#ifdef _WIN64
(FARPROC) PathParseIconLocation;
#else
GetSysProcAddr("SHLWAPI", sizeof(TCHAR) == 1 ? "PathParseIconLocationA" : "PathParseIconLocationW");
if (!dd.PPIL || (SupportsWNT4() || IsWin9598ME()))
{
(FARPROC&) dd.PPIL = GetSysProcAddr("SHELL32", (LPCSTR) 249); // PathParseIconLocationT
if (sizeof(TCHAR) == 1) (FARPROC&) dd.PPIL = (FARPROC) PathParseIconLocationFallback<CHAR>;
}
#endif
return DialogBoxParam(HINST_APPLICATION, MAKEINTRESOURCE(DLG_LOOKUP), hOwner, LookupDlgProc, (LPARAM) &dd);
}

View file

@ -45,6 +45,7 @@ NFINDREPLACE g_find;
TCHAR g_findbuf[128];
extern NTOOLBAR g_toolbar;
void* g_ModalDlgData;
BYTE g_MiniCommand = false;
NSIS_ENTRYPOINT_SIMPLEGUI
int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int ShowCmd) {
@ -86,12 +87,12 @@ int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int
return 1;
}
ResetObjects();
HACCEL haccel = LoadAccelerators(g_sdata.hInstance, MAKEINTRESOURCE(IDK_ACCEL));
HWND hDialog = CreateDialog(g_sdata.hInstance,MAKEINTRESOURCE(DLG_MAIN),0,DialogProc);
if (!hDialog) {
if (!hDialog && !g_MiniCommand) {
MessageBox(0,DLGERROR,ERRBOXTITLE,MB_ICONEXCLAMATION|MB_OK|MB_TASKMODAL);
return 1;
}
HACCEL haccel = LoadAccelerators(g_sdata.hInstance, MAKEINTRESOURCE(IDK_ACCEL));
MSG msg;
int status;
while ((status=GetMessage(&msg,0,0,0))!=0) {
@ -146,22 +147,21 @@ static void AddScriptCmdArgs(const TCHAR *arg)
GlobalUnlock(g_sdata.script_cmd_args);
}
static void ProcessCommandLine()
enum { CMD_PICKCOMP = 0x0001, CMD_SPY = 0x0080, CMD_LOOKUP = 0x8000 };
static UINT ProcessCommandLine()
{
TCHAR **argv;
int i, j;
int i, j, retflags = 0;
int argc = SetArgv((TCHAR *)GetCommandLine(), &argv);
if (argc > 1) {
for (i = 1; i < argc; i++)
{
if (!StrCmpNI(argv[i], _T("/XSetCompressor "), lstrlen(_T("/XSetCompressor "))))
if (!lstrcmpi(argv[i], _T("/Spy"))) retflags |= CMD_SPY;
else if (!lstrcmpi(argv[i], _T("/Lookup"))) retflags |= CMD_LOOKUP;
else if (!StrCmpNI(argv[i], _T("/XSetCompressor "), COUNTOF("/XSetCompressor ") - !0))
{
TCHAR *p = argv[i] + lstrlen(_T("/XSetCompressor "));
if(!StrCmpNI(p,_T("/FINAL "), lstrlen(_T("/FINAL "))))
{
p += lstrlen(_T("/FINAL "));
}
TCHAR *p = argv[i] + lstrlen(_T("/XSetCompressor ")), cchSlashFinalSpace = COUNTOF("/FINAL ") - !0;
if (!StrCmpNI(p,_T("/FINAL "), cchSlashFinalSpace)) p += cchSlashFinalSpace;
while (*p == _T(' ')) p++;
for (j = (int) COMPRESSOR_SCRIPT + 1; j < (int) COMPRESSOR_BEST; j++)
@ -174,7 +174,7 @@ static void ProcessCommandLine()
}
else if (!lstrcmpi(argv[i], _T("/ChooseCompressor")))
{
g_sdata.userSelectCompressor = TRUE;
retflags |= CMD_PICKCOMP;
}
else if (argv[i][0] == _T('-') || argv[i][0] == _T('/'))
{
@ -189,6 +189,7 @@ static void ProcessCommandLine()
}
}
MemSafeFree(argv);
return retflags;
}
DWORD CALLBACK SaveFileStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
@ -261,7 +262,6 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
// Altered by Darren Owen (DrO) on 29/9/2003
// Added in receiving of mouse and key events from the richedit control
SendDlgItemMessage(hwndDlg,IDC_LOGWIN,EM_SETEVENTMASK,(WPARAM)NULL,ENM_SELCHANGE|ENM_MOUSEEVENTS|ENM_KEYEVENTS);
DragAcceptFiles(g_sdata.hwnd,FALSE);
g_sdata.menu = GetMenu(g_sdata.hwnd);
g_sdata.fileSubmenu = FindSubMenu(g_sdata.menu, IDM_FILE);
g_sdata.editSubmenu = FindSubMenu(g_sdata.menu, IDM_EDIT);
@ -286,20 +286,27 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
}
HFONT hFont = CreateFontPt(hwndDlg,fontsize,FW_NORMAL,FIXED_PITCH|FF_DONTCARE,fontcharset,fontname);
SendDlgItemMessage(hwndDlg,IDC_LOGWIN,WM_SETFONT,(WPARAM)hFont,0);
RestoreWindowPos(g_sdata.hwnd);
RestoreCompressor();
SetScript(_T(""));
g_sdata.compressor = COMPRESSOR_NONE_SELECTED;
g_sdata.userSelectCompressor = FALSE;
SetScript(_T(""));
RestoreCompressor();
ToolBarSizeChanged(hwndDlg);
ProcessCommandLine();
UINT docmd = ProcessCommandLine();
if ((docmd & (CMD_SPY|CMD_LOOKUP)))
{
INT_PTR r = ((docmd & CMD_LOOKUP) ? ShowLookupDialog : ShowWndSpy)(0);
g_sdata.hwnd = NULL; // Don't save window pos
g_MiniCommand++;
return SendMessage(hwndDlg, WM_CLOSE, r, r);
}
RestoreWindowPos(g_sdata.hwnd);
if(g_sdata.compressor == COMPRESSOR_NONE_SELECTED) {
SetCompressor(g_sdata.default_compressor);
}
if(g_sdata.userSelectCompressor) {
if(docmd & CMD_PICKCOMP) {
if (DialogBox(g_sdata.hInstance,MAKEINTRESOURCE(DLG_COMPRESSOR),g_sdata.hwnd,API_cast<DLGPROC>(CompressorProc))) {
EnableItems(g_sdata.hwnd);
return TRUE;
@ -320,7 +327,6 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
}
case WM_DESTROY:
{
DragAcceptFiles(g_sdata.hwnd, FALSE);
SaveSymbols();
SaveMRUList();
SaveWindowPos(g_sdata.hwnd);
@ -331,10 +337,11 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
PostQuitMessage(0);
return TRUE;
}
case WM_CLOSE:
case WM_CLOSE: tryquitapp:
{
if (!g_sdata.thread) {
DestroyWindow(hwndDlg);
PostQuitMessage((int) wParam);
}
return TRUE;
}
@ -699,11 +706,8 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
DialogBox(g_sdata.hInstance,MAKEINTRESOURCE(DLG_SETTINGS),g_sdata.hwnd,API_cast<DLGPROC>(SettingsProc));
return TRUE;
}
case IDM_WNDSPY:
{
extern INT_PTR ShowWndSpy(HWND hOwner);
return ShowWndSpy(g_sdata.hwnd);
}
case IDM_WNDSPY: return ShowWndSpy(hwndDlg);
case IDM_LOOKUP: return ShowLookupDialog(hwndDlg);
case IDM_GUIDGEN:
{
GUID guid;
@ -740,12 +744,8 @@ INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
}
case IDCANCEL:
case IDM_EXIT:
{
if (!g_sdata.thread) {
DestroyWindow(g_sdata.hwnd);
}
return TRUE;
}
wParam = 0;
goto tryquitapp;
case IDM_CANCEL:
{
SetEvent(g_sdata.sigint_event);

View file

@ -39,6 +39,9 @@
#define SupportsW95() ( FALSE && SupportsW9X() && !DpiAwarePerMonitor() )
#define SupportsW2000() ( sizeof(void*) == 4 )
static bool IsWin9598ME() { return SupportsW9X() && (int) GetVersion() < 0; }
static bool IsWin95() { return SupportsW95() && (GetVersion() & (0x8000FFFF & ~0x0300)) == 0x80000004; }
// Defines
#define NSIS_URL "https://nsis.sourceforge.io/"
#define NSIS_FORUM_URL "http://forums.winamp.com/forumdisplay.php?forumid=65"
@ -220,7 +223,6 @@ typedef struct NSISScriptData {
char *brandingv;
TCHAR **symbols;
int retcode;
bool userSelectCompressor;
unsigned char verbosity;
DWORD logLength;
DWORD warnings;
@ -265,4 +267,8 @@ typedef struct ToolTipStruct {
HHOOK hook;
} NTOOLTIP;
extern INT_PTR ShowWndSpy(HWND hOwner);
extern INT_PTR ShowLookupDialog(HWND hOwner);
#endif

View file

@ -37,6 +37,7 @@
#define IDB_LOGO 115
#define DLG_SETTINGS 116
#define DLG_WNDSPY 117
#define DLG_LOOKUP 118
#define IDB_TOOLBAR 122
#define DLG_COMPRESSOR 124
#define DLG_SYMBOLSET 125
@ -83,6 +84,11 @@
#define IDC_WNDPHYSSIZE 227
#define IDC_WNDINFO 229
#define IDC_WNDDPI 230
#define IDC_LUMODE 220
#define IDC_LUEXTRALABEL 221
#define IDC_LUEXTRATEXT 222
#define IDC_LUOUTPUTTEXT 223
#define IDC_LUOUTPUTICON 224
#define IDM_MRU_FILE 6000
#define IDM_CMDBASE 500
@ -127,6 +133,7 @@
#define IDM_UI_SWITCHOWNEDWINDOW 538 // Alt+F6
#define IDM_UI_SWITCHSECTION 539 // F6
#define IDM_GUIDGEN 540
#define IDM_LOOKUP 541
// Next default values for new objects
@ -134,7 +141,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 138
#define _APS_NEXT_COMMAND_VALUE 541
#define _APS_NEXT_COMMAND_VALUE 542
#define _APS_NEXT_CONTROL_VALUE 241
#define _APS_NEXT_SYMED_VALUE 101
#endif

View file

@ -111,6 +111,7 @@ BEGIN
MENUITEM "&Settings\tCtrl+S", IDM_SETTINGS
MENUITEM "", -1, MFT_SEPARATOR
MENUITEM "&Window Info", IDM_WNDSPY
MENUITEM "&Lookup", IDM_LOOKUP
MENUITEM "Generate &GUID", IDM_GUIDGEN
MENUITEM "", -1, MFT_SEPARATOR
MENUITEM "Clear Recent &Files List", IDM_CLEAR_MRU_LIST
@ -249,7 +250,7 @@ BEGIN
END
DLG_WNDSPY DIALOGEX 0, 0, 236, 130
STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "Window Info"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
@ -275,6 +276,18 @@ BEGIN
CONTROL "", IDC_WNDDPI, "Edit", ES_LEFT | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL , 39, 114, 190, 10
END
DLG_LOOKUP DIALOGEX 0, 0, 301, 150
STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "Lookup"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
CONTROL "Source", -1, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 7, 285, 65
CONTROL "", IDC_LUMODE, COMBOBOX, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 16, 20, 268, 114
CONTROL "", IDC_LUEXTRALABEL, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 16, 38, 268, 10
CONTROL "", IDC_LUEXTRATEXT, EDIT, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 16, 50, 268, 14
CONTROL "", IDC_LUOUTPUTTEXT, EDIT, ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 7, 80, 286, 60
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO

View file

@ -60,6 +60,9 @@ HMODULE LoadSysLibrary(LPCSTR Mod)
return LoadLibrary(path);
}
#ifdef DECLSPEC_NOINLINE
DECLSPEC_NOINLINE
#endif
FARPROC GetSysProcAddr(LPCSTR Mod, LPCSTR FuncName)
{
return GetProcAddress(LoadSysLibrary(Mod), FuncName);
@ -436,7 +439,7 @@ static DWORD RegReadString(HKEY hKey, LPCTSTR Name, LPTSTR Buf, DWORD cbBufSize)
return ec;
}
static DWORD RegOpenKeyForReading(HKEY hRoot, LPCTSTR SubKey, HKEY*pKey) {
DWORD RegOpenKeyForReading(HKEY hRoot, LPCTSTR SubKey, HKEY*pKey) {
return RegOpenKeyEx(hRoot, SubKey, 0, KEY_READ, pKey);
}
@ -519,9 +522,9 @@ void SaveWindowPos(HWND hwnd) {
HKEY hKey;
WINDOWPLACEMENT p;
p.length = sizeof(p);
GetWindowPlacement(hwnd, &p);
if (CreateRegSettingsKey(hKey)) {
RegSetValueEx(hKey, REGLOC, 0, REG_BINARY, (LPBYTE)&p, sizeof(p));
if (!GetWindowPlacement(hwnd, &p)) p.length = 0;
if (p.length && CreateRegSettingsKey(hKey)) {
RegSetValueEx(hKey, REGLOC, 0, REG_BINARY, (LPBYTE)&p, p.length);
RegCloseKey(hKey);
}
}

View file

@ -111,6 +111,29 @@ struct FSPath {
}
};
template<class T> UINT StrLenT(const T*s) { return sizeof(T) > 1 ? lstrlenW((WCHAR*) s) : lstrlenA((CHAR*) s) ; }
template<class T> T AsciiLoCh(T ch) { return ch >= 'A' && ch <= 'Z' ? (ch | 32) : ch; }
template<class A, class B> int AsciiCmpNI(const A*a, const B*b, SIZE_T len)
{
int cmp = 0;
for (SIZE_T i = 0;; ++i)
if (i == len || (cmp = AsciiLoCh(a[i]) - AsciiLoCh(b[i])) || !a[i])
return cmp;
}
template<class A, class B> inline bool AsciiMatchNI(const A*a, const B*b, SIZE_T c) { return !AsciiCmpNI(a, b, c); }
template<class A, class B> bool AsciiMatchPrefixI(const A*s, const B*p) { return AsciiMatchNI(s, p, StrLenT(p)); }
template<class T> HKEY GetRegRootKey(const T*Str)
{
if (AsciiMatchPrefixI(Str, "HKEY_CLASSES_ROOT") || AsciiMatchPrefixI(Str, "HKCR")) return HKEY_CLASSES_ROOT;
if (AsciiMatchPrefixI(Str, "HKEY_CURRENT_USER") || AsciiMatchPrefixI(Str, "HKCU")) return HKEY_CURRENT_USER;
if (AsciiMatchPrefixI(Str, "HKEY_LOCAL_MACHINE") || AsciiMatchPrefixI(Str, "HKLM")) return HKEY_LOCAL_MACHINE;
if (AsciiMatchPrefixI(Str, "HKEY_USERS") || AsciiMatchPrefixI(Str, "HKU")) return HKEY_USERS;
return (HKEY) NULL;
}
DWORD RegOpenKeyForReading(HKEY hRoot, LPCTSTR SubKey, HKEY*pKey);
bool FileExists(const TCHAR *fname);
bool OpenUrlInDefaultBrowser(HWND hwnd, LPCSTR Url);

View file

@ -106,6 +106,7 @@ typedef struct _DIALOGDATA {
int DialogAwarenessContext; // Canonical DPI awareness context
_DIALOGDATA() : hWndOutline(0) {}
static struct _DIALOGDATA* Get(HWND hDlg) { return (struct _DIALOGDATA*) GetWindowLongPtr(hDlg, DWLP_USER); }
static void Set(HWND hDlg, void*pDD) { SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pDD); }
} DIALOGDATA;
typedef struct {
@ -281,7 +282,7 @@ static INT_PTR CALLBACK SpyDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM LP
switch(Msg)
{
case WM_INITDIALOG:
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) (pDD = (DIALOGDATA*) LParam));
DIALOGDATA::Set(hDlg, (pDD = (DIALOGDATA*) LParam));
CenterOnParent(hDlg);
// On >= 10FU1703 we are PMv2 and Windows scales our dialog and child controls.
// On >= 10FU1607 && < 10FU1703 we are System aware but try to upgrade this thread to
@ -336,7 +337,10 @@ static INT_PTR CALLBACK SpyDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM LP
RECT r;
GetPhysicalWindowRect(pDD->hWndTarget, r, hDlg), PhysicalToLogical(pDD->hWndOutline, r, hDlg);
if (GetAncestor(pDD->hWndTarget, GA_ROOT) != hDlg)
SetWindowPos(pDD->hWndOutline, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_SHOWWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
{
SetWindowPos(pDD->hWndOutline, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_HIDEWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
ShowWindow(pDD->hWndOutline, SW_SHOW); // To avoid a small Windows redraw bug, don't show the window until after it has the correct size
}
SetTimer(hDlg, TID_OUTLINE, 2 * 1000, NULL);
}
ReleaseCapture();