| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106 |
- //---------------------------------------------------------------------------
- #define NO_WIN32_LEAN_AND_MEAN
- #include <vcl.h>
- #pragma hdrstop
- #include <Consts.hpp>
- #include <shlobj.h>
- #include <stdio.h>
- #include <Common.h>
- #include <TextsWin.h>
- #include <Exceptions.h>
- #include <Configuration.h>
- #include <CoreMain.h>
- #include "GUITools.h"
- #include "VCLCommon.h"
- #include "Setup.h"
- #include "Tools.h"
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- //---------------------------------------------------------------------------
- TFontStyles __fastcall IntToFontStyles(int value)
- {
- TFontStyles Result;
- for (int i = fsBold; i <= fsStrikeOut; i++)
- {
- if (value & 1)
- {
- Result << (TFontStyle)i;
- }
- value >>= 1;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- int __fastcall FontStylesToInt(const TFontStyles value)
- {
- int Result = 0;
- for (int i = fsStrikeOut; i >= fsBold; i--)
- {
- Result <<= 1;
- if (value.Contains((TFontStyle)i))
- {
- Result |= 1;
- }
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall CenterFormOn(TForm * Form, TControl * CenterOn)
- {
- TPoint ScreenPoint = CenterOn->ClientToScreen(TPoint(0, 0));
- Form->Left = ScreenPoint.x + (CenterOn->Width / 2) - (Form->Width / 2);
- Form->Top = ScreenPoint.y + (CenterOn->Height / 2) - (Form->Height / 2);
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall GetListViewStr(TListView * ListView)
- {
- AnsiString Result;
- for (int Index = 0; Index < ListView->Columns->Count; Index++)
- {
- if (!Result.IsEmpty())
- {
- Result += ",";
- }
- Result += IntToStr(ListView->Column[Index]->Width);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall LoadListViewStr(TListView * ListView, AnsiString LayoutStr)
- {
- int Index = 0;
- while (!LayoutStr.IsEmpty() && (Index < ListView->Columns->Count))
- {
- ListView->Column[Index]->Width = StrToIntDef(
- CutToChar(LayoutStr, ',', true), ListView->Column[Index]->Width);
- Index++;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall RestoreForm(AnsiString Data, TForm * Form)
- {
- assert(Form);
- if (!Data.IsEmpty())
- {
- TMonitor * Monitor = FormMonitor(Form);
- TRect Bounds = Form->BoundsRect;
- int Left = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Left);
- int Top = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Top);
- bool DefaultPos = (Left == -1) && (Top == -1);
- if (!DefaultPos)
- {
- Bounds.Left = Left;
- Bounds.Top = Top;
- }
- else
- {
- Bounds.Left = 0;
- Bounds.Top = 0;
- }
- Bounds.Right = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Right);
- Bounds.Bottom = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Bottom);
- TWindowState State = (TWindowState)StrToIntDef(::CutToChar(Data, ';', true), (int)wsNormal);
- Form->WindowState = State;
- if (State == wsNormal)
- {
- // move to the target monitor
- OffsetRect(Bounds, Monitor->Left, Monitor->Top);
- // reduce window size to that of monitor size
- // (this does not cut window into monitor!)
- if (Bounds.Width() > Monitor->WorkareaRect.Width())
- {
- Bounds.Right -= (Bounds.Width() - Monitor->WorkareaRect.Width());
- }
- if (Bounds.Height() > Monitor->WorkareaRect.Height())
- {
- Bounds.Bottom -= (Bounds.Height() - Monitor->WorkareaRect.Height());
- }
- if (DefaultPos ||
- ((Bounds.Left < Monitor->Left) ||
- (Bounds.Left > Monitor->Left + Monitor->WorkareaRect.Width() - 20) ||
- (Bounds.Top < Monitor->Top) ||
- (Bounds.Top > Monitor->Top + Monitor->WorkareaRect.Height() - 20)))
- {
- if (Monitor->Primary)
- {
- if ((Application->MainForm == NULL) || (Application->MainForm == Form))
- {
- Form->Position = poDefaultPosOnly;
- }
- else
- {
- Form->Position = poMainFormCenter;
- }
- Form->Width = Bounds.Width();
- Form->Height = Bounds.Height();
- }
- else
- {
- // when positioning on non-primary monitor, we need
- // to handle that ourselves, so place window to center
- Form->SetBounds(Monitor->Left + ((Monitor->Width - Bounds.Width()) / 2),
- Monitor->Top + ((Monitor->Height - Bounds.Height()) / 2),
- Bounds.Width(), Bounds.Height());
- Form->Position = poDesigned;
- }
- }
- else
- {
- Form->Position = poDesigned;
- Form->BoundsRect = Bounds;
- }
- }
- else if (State == wsMaximized)
- {
- Form->Position = poDesigned;
- Bounds = Form->BoundsRect;
- OffsetRect(Bounds, Monitor->Left, Monitor->Top);
- Form->BoundsRect = Bounds;
- }
- }
- else if (Form->Position == poDesigned)
- {
- Form->Position = poDefaultPosOnly;
- }
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall StoreForm(TCustomForm * Form)
- {
- assert(Form);
- TRect Bounds = Form->BoundsRect;
- OffsetRect(Bounds, -Form->Monitor->Left, -Form->Monitor->Top);
- return FORMAT("%d;%d;%d;%d;%d", ((int)Bounds.Left, (int)Bounds.Top,
- (int)Bounds.Right, (int)Bounds.Bottom,
- // we do not want WinSCP to start minimized next time (we cannot handle that anyway).
- // note that WindowState is wsNormal when window in minimized for some reason.
- // actually it is wsMinimized only when minimized by MSVDM
- (int)(Form->WindowState == wsMinimized ? wsNormal : Form->WindowState)));
- }
- //---------------------------------------------------------------------------
- void __fastcall RestoreFormSize(AnsiString Data, TForm * Form)
- {
- int Width = StrToIntDef(CutToChar(Data, ',', true), Form->Width);
- int Height = StrToIntDef(CutToChar(Data, ',', true), Form->Height);
- ResizeForm(Form, Width, Height);
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall StoreFormSize(TForm * Form)
- {
- return FORMAT("%d,%d", (Form->Width, Form->Height));
- }
- //---------------------------------------------------------------------------
- bool __fastcall ExecuteShellAndWait(const AnsiString Path, const AnsiString Params)
- {
- return ExecuteShellAndWait(Application->Handle, Path, Params,
- &Application->ProcessMessages);
- }
- //---------------------------------------------------------------------------
- bool __fastcall ExecuteShellAndWait(const AnsiString Command)
- {
- return ExecuteShellAndWait(Application->Handle, Command,
- &Application->ProcessMessages);
- }
- //---------------------------------------------------------------------------
- void __fastcall CreateDesktopShortCut(const AnsiString & Name,
- const AnsiString &File, const AnsiString & Params, const AnsiString & Description,
- int SpecialFolder)
- {
- IShellLink* pLink;
- IPersistFile* pPersistFile;
- LPMALLOC ShellMalloc;
- LPITEMIDLIST DesktopPidl;
- char DesktopDir[MAX_PATH];
- if (SpecialFolder < 0)
- {
- SpecialFolder = CSIDL_DESKTOPDIRECTORY;
- }
- try
- {
- if (FAILED(SHGetMalloc(&ShellMalloc))) throw Exception("");
- if (FAILED(SHGetSpecialFolderLocation(NULL, SpecialFolder, &DesktopPidl)))
- {
- throw Exception("");
- }
- if (!SHGetPathFromIDList(DesktopPidl, DesktopDir))
- {
- ShellMalloc->Free(DesktopPidl);
- ShellMalloc->Release();
- throw Exception("");
- }
- ShellMalloc->Free(DesktopPidl);
- ShellMalloc->Release();
- if (SUCCEEDED(CoInitialize(NULL)))
- {
- if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- IID_IShellLink, (void **) &pLink)))
- {
- try
- {
- pLink->SetPath(File.c_str());
- pLink->SetDescription(Description.c_str());
- pLink->SetArguments(Params.c_str());
- pLink->SetShowCmd(SW_SHOW);
- // if there's .ico file with the same name as the .exe,
- // use it for shortcut (so ours 128px icons is used, when available,
- // instead of the 32px embedded one)
- AnsiString IconFile = ChangeFileExt(File, ".ico");
- if (FileExists(IconFile))
- {
- pLink->SetIconLocation(IconFile.c_str(), 0);
- }
- if (SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile)))
- {
- try
- {
- WideString strShortCutLocation(DesktopDir);
- // Name can contain even path (e.g. to create quick launch icon)
- strShortCutLocation += AnsiString("\\") + Name + ".lnk";
- if (!SUCCEEDED(pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE)))
- {
- RaiseLastOSError();
- }
- }
- __finally
- {
- pPersistFile->Release();
- }
- }
- }
- __finally
- {
- pLink->Release();
- }
- }
- CoUninitialize();
- }
- }
- catch(Exception & E)
- {
- throw ExtException(&E, LoadStr(CREATE_SHORTCUT_ERROR));
- }
- }
- //---------------------------------------------------------------------------
- template<class TEditControl>
- void __fastcall ValidateMaskEditT(TEditControl * Edit)
- {
- assert(Edit != NULL);
- TFileMasks Masks;
- try
- {
- Masks = Edit->Text;
- }
- catch(EFileMasksException & E)
- {
- ShowExtendedException(&E);
- Edit->SetFocus();
- Edit->SelStart = E.ErrorStart - 1;
- Edit->SelLength = E.ErrorLen;
- Abort();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall ValidateMaskEdit(TComboBox * Edit)
- {
- ValidateMaskEditT(Edit);
- }
- //---------------------------------------------------------------------------
- void __fastcall ValidateMaskEdit(TEdit * Edit)
- {
- ValidateMaskEditT(Edit);
- }
- //---------------------------------------------------------------------------
- void __fastcall ExitActiveControl(TForm * Form)
- {
- if (Form->ActiveControl != NULL)
- {
- TNotifyEvent OnExit = ((TEdit*)Form->ActiveControl)->OnExit;
- if (OnExit != NULL)
- {
- OnExit(Form->ActiveControl);
- }
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall OpenBrowser(AnsiString URL)
- {
- AnsiString HomePageUrl = LoadStr(HOMEPAGE_URL);
- if (AnsiSameText(URL.SubString(1, HomePageUrl.Length()), HomePageUrl))
- {
- URL = CampaignUrl(URL);
- }
- ShellExecute(Application->Handle, "open", URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
- }
- //---------------------------------------------------------------------------
- bool __fastcall IsFormatInClipboard(unsigned int Format)
- {
- bool Result = OpenClipboard(0);
- if (Result)
- {
- Result = IsClipboardFormatAvailable(Format);
- CloseClipboard();
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- HANDLE __fastcall OpenTextFromClipboard(const char *& Text)
- {
- HANDLE Result = NULL;
- if (OpenClipboard(0))
- {
- Result = GetClipboardData(CF_TEXT);
- if (Result != NULL)
- {
- Text = static_cast<const char*>(GlobalLock(Result));
- }
- else
- {
- CloseClipboard();
- }
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall CloseTextFromClipboard(HANDLE Handle)
- {
- if (Handle != NULL)
- {
- GlobalUnlock(Handle);
- }
- CloseClipboard();
- }
- //---------------------------------------------------------------------------
- bool __fastcall TextFromClipboard(AnsiString & Text)
- {
- const char * AText = NULL;
- HANDLE Handle = OpenTextFromClipboard(AText);
- bool Result = (Handle != NULL);
- if (Result)
- {
- Text = AText;
- CloseTextFromClipboard(Handle);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall VersionStrFromCompoundVersion(int Version)
- {
- int MajorVer = Version / (10000*100*100);
- int MinorVer = (Version % (10000*100*100)) / (10000*100);
- int Release = (Version % (10000*100)) / (10000);
- AnsiString Result;
- if (Release > 0)
- {
- Result = FORMAT("%d.%d.%d", (MajorVer, MinorVer, Release));
- }
- else
- {
- Result = FORMAT("%d.%d", (MajorVer, MinorVer));
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall CampaignUrl(AnsiString URL)
- {
- if (URL.Pos("?") == 0)
- {
- URL += "?";
- }
- else
- {
- URL += "&";
- }
- int CurrentCompoundVer = Configuration->CompoundVersion;
- AnsiString Version = VersionStrFromCompoundVersion(CurrentCompoundVer);
- URL += FORMAT("utm_source=winscp&utm_medium=app&utm_campaign=%s", (Version));
- return URL;
- }
- //---------------------------------------------------------------------------
- static bool __fastcall GetResource(
- const AnsiString ResName, void *& Content, unsigned long & Size)
- {
- HRSRC Resource = FindResourceEx(HInstance, RT_RCDATA, ResName.c_str(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
- bool Result = (Resource != NULL);
- if (Result)
- {
- Size = SizeofResource(HInstance, Resource);
- if (!Size)
- {
- throw Exception(FORMAT("Cannot get size of resource %s", (ResName)));
- }
- Content = LoadResource(HInstance, Resource);
- if (!Content)
- {
- throw Exception(FORMAT("Cannot read resource %s", (ResName)));
- }
- Content = LockResource(Content);
- if (!Content)
- {
- throw Exception(FORMAT("Cannot lock resource %s", (ResName)));
- }
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- bool __fastcall DumpResourceToFile(const AnsiString ResName,
- const AnsiString FileName)
- {
- void * Content;
- unsigned long Size;
- bool Result = GetResource(ResName, Content, Size);
- if (Result)
- {
- FILE * f = fopen(FileName.c_str(), "wb");
- if (!f)
- {
- throw Exception(FORMAT("Cannot create file %s", (FileName)));
- }
- if (fwrite(Content, 1, Size, f) != Size)
- {
- throw Exception(FORMAT("Cannot write to file %s", (FileName)));
- }
- fclose(f);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall ReadResource(const AnsiString ResName)
- {
- void * Content;
- unsigned long Size;
- AnsiString Result;
- if (GetResource(ResName, Content, Size))
- {
- Result = AnsiString(static_cast<char*>(Content), Size);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- template <class T>
- class TChildCommonDialog : public T
- {
- public:
- __fastcall TChildCommonDialog(TComponent * AOwner) :
- T(AOwner)
- {
- }
- protected:
- // all common-dialog structures we use (save, open, font) start like this:
- typedef struct
- {
- DWORD lStructSize;
- HWND hwndOwner;
- } COMMONDLG;
- virtual BOOL __fastcall TaskModalDialog(void * DialogFunc, void * DialogData)
- {
- COMMONDLG * CommonDlg = static_cast<COMMONDLG *>(DialogData);
- HWND Parent = GetCorrectFormParent();
- if (Parent != NULL)
- {
- CommonDlg->hwndOwner = Parent;
- }
- return T::TaskModalDialog(DialogFunc, DialogData);
- }
- };
- //---------------------------------------------------------------------------
- // without this intermediate class, failure occurs during construction in release version
- #define CHILDCOMMONDIALOG(DIALOG) \
- class TChild ## DIALOG ## Dialog : public TChildCommonDialog<T ## DIALOG ## Dialog> \
- { \
- public: \
- __fastcall TChild ## DIALOG ## Dialog(TComponent * AOwner) : \
- TChildCommonDialog<T ## DIALOG ## Dialog>(AOwner) \
- { \
- } \
- }
- //---------------------------------------------------------------------------
- CHILDCOMMONDIALOG(Open);
- CHILDCOMMONDIALOG(Save);
- CHILDCOMMONDIALOG(Font);
- //---------------------------------------------------------------------------
- TOpenDialog * __fastcall CreateOpenDialog(TComponent * AOwner)
- {
- return new TChildOpenDialog(AOwner);
- }
- //---------------------------------------------------------------------------
- template <class T>
- void __fastcall BrowseForExecutableT(T * Control, AnsiString Title,
- AnsiString Filter, bool FileNameCommand, bool Escape)
- {
- AnsiString Executable, Program, Params, Dir;
- Executable = Control->Text;
- if (FileNameCommand)
- {
- ReformatFileNameCommand(Executable);
- }
- SplitCommand(Executable, Program, Params, Dir);
- TOpenDialog * FileDialog = CreateOpenDialog(Application);
- try
- {
- if (Escape)
- {
- Program = StringReplace(Program, "\\\\", "\\", TReplaceFlags() << rfReplaceAll);
- }
- AnsiString ExpandedProgram = ExpandEnvironmentVariables(Program);
- FileDialog->FileName = ExpandedProgram;
- FileDialog->Filter = Filter;
- FileDialog->Title = Title;
- if (FileDialog->Execute())
- {
- TNotifyEvent PrevOnChange = Control->OnChange;
- Control->OnChange = NULL;
- try
- {
- // preserve unexpanded file, if the destination has not changed actually
- if (!CompareFileName(ExpandedProgram, FileDialog->FileName))
- {
- Program = FileDialog->FileName;
- if (Escape)
- {
- Program = StringReplace(Program, "\\", "\\\\", TReplaceFlags() << rfReplaceAll);
- }
- }
- Control->Text = FormatCommand(Program, Params);
- }
- __finally
- {
- Control->OnChange = PrevOnChange;
- }
- if (Control->OnExit != NULL)
- {
- Control->OnExit(Control);
- }
- }
- }
- __finally
- {
- delete FileDialog;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall BrowseForExecutable(TEdit * Control, AnsiString Title,
- AnsiString Filter, bool FileNameCommand, bool Escape)
- {
- BrowseForExecutableT(Control, Title, Filter, FileNameCommand, Escape);
- }
- //---------------------------------------------------------------------------
- void __fastcall BrowseForExecutable(TComboBox * Control, AnsiString Title,
- AnsiString Filter, bool FileNameCommand, bool Escape)
- {
- BrowseForExecutableT(Control, Title, Filter, FileNameCommand, Escape);
- }
- //---------------------------------------------------------------------------
- bool __fastcall FontDialog(TFont * Font)
- {
- bool Result;
- TFontDialog * Dialog = new TChildFontDialog(Application);
- try
- {
- Dialog->Device = fdScreen;
- Dialog->Options = TFontDialogOptions() << fdForceFontExist;
- Dialog->Font = Font;
- Result = Dialog->Execute();
- if (Result)
- {
- Font->Assign(Dialog->Font);
- }
- }
- __finally
- {
- delete Dialog;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- bool __fastcall SaveDialog(AnsiString Title, AnsiString Filter,
- AnsiString DefaultExt, AnsiString & FileName)
- {
- bool Result;
- TSaveDialog * Dialog = new TChildSaveDialog(Application);
- try
- {
- Dialog->Title = Title;
- Dialog->Filter = Filter;
- Dialog->DefaultExt = DefaultExt;
- Dialog->FileName = FileName;
- Dialog->Options = Dialog->Options << ofOverwritePrompt << ofPathMustExist <<
- ofNoReadOnlyReturn;
- Result = Dialog->Execute();
- if (Result)
- {
- FileName = Dialog->FileName;
- }
- }
- __finally
- {
- delete Dialog;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall CopyToClipboard(AnsiString Text)
- {
- HANDLE Data;
- void * DataPtr;
- if (OpenClipboard(0))
- {
- try
- {
- Data = GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, Text.Length() + 1);
- try
- {
- DataPtr = GlobalLock(Data);
- try
- {
- memcpy(DataPtr, Text.c_str(), Text.Length() + 1);
- EmptyClipboard();
- SetClipboardData(CF_TEXT, Data);
- }
- __finally
- {
- GlobalUnlock(Data);
- }
- }
- catch(...)
- {
- GlobalFree(Data);
- throw;
- }
- }
- __finally
- {
- CloseClipboard();
- }
- }
- else
- {
- throw Exception(Consts_SCannotOpenClipboard);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall CopyToClipboard(TStrings * Strings)
- {
- if (Strings->Count > 0)
- {
- if (Strings->Count == 1)
- {
- CopyToClipboard(Strings->Strings[0]);
- }
- else
- {
- CopyToClipboard(Strings->Text);
- }
- }
- }
- //---------------------------------------------------------------------------
- bool __fastcall IsWin64()
- {
- static int Result = -1;
- if (Result < 0)
- {
- typedef BOOL WINAPI (*IsWow64ProcessType)(HANDLE Process, PBOOL Wow64Process);
- Result = 0;
- HMODULE Kernel = GetModuleHandle(kernel32);
- if (Kernel != NULL)
- {
- IsWow64ProcessType IsWow64Process =
- (IsWow64ProcessType)GetProcAddress(Kernel, "IsWow64Process");
- if (IsWow64Process != NULL)
- {
- BOOL Wow64Process = FALSE;
- if (IsWow64Process(GetCurrentProcess(), &Wow64Process))
- {
- if (Wow64Process)
- {
- Result = 1;
- }
- }
- }
- }
- }
- return (Result > 0);
- }
- //---------------------------------------------------------------------------
- void __fastcall ShutDownWindows()
- {
- HANDLE Token;
- TOKEN_PRIVILEGES Priv;
- // Get a token for this process.
- Win32Check(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token));
- // Get the LUID for the shutdown privilege.
- Win32Check(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &Priv.Privileges[0].Luid));
- Priv.PrivilegeCount = 1; // one privilege to set
- Priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- // Get the shutdown privilege for this process.
- Win32Check(AdjustTokenPrivileges(Token, FALSE, &Priv, 0, (PTOKEN_PRIVILEGES)NULL, 0));
- // Shut down the system and force all applications to close.
- Win32Check(ExitWindowsEx(EWX_SHUTDOWN | EWX_POWEROFF,
- SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED));
- }
- //---------------------------------------------------------------------------
- void __fastcall EditSelectBaseName(HWND Edit)
- {
- AnsiString Text;
- Text.SetLength(GetWindowTextLength(Edit) + 1);
- GetWindowText(Edit, Text.c_str(), Text.Length());
- int P = Text.LastDelimiter(".");
- if (P > 0)
- {
- // SendMessage does not work, if edit control is not fully
- // initialized yet
- PostMessage(Edit, EM_SETSEL, 0, P - 1);
- }
- }
- //---------------------------------------------------------------------------
- // Code from http://gentoo.osuosl.org/distfiles/cl331.zip/io/
- // The autoproxy functions were only documented in WinHTTP 5.1, so we have to
- // provide the necessary defines and structures ourselves
- #ifndef WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
- #define HINTERNET HANDLE
- typedef struct
- {
- WORD dwAccessType;
- LPWSTR lpszProxy;
- LPWSTR lpszProxyBypass;
- } WINHTTP_PROXY_INFO;
- typedef struct {
- BOOL fAutoDetect;
- LPWSTR lpszAutoConfigUrl;
- LPWSTR lpszProxy;
- LPWSTR lpszProxyBypass;
- } WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
- #endif /* WinHTTP 5.1 defines and structures */
- typedef BOOL (*WINHTTPGETDEFAULTPROXYCONFIGURATION)(WINHTTP_PROXY_INFO * pProxyInfo);
- typedef BOOL (*WINHTTPGETIEPROXYCONFIGFORCURRENTUSER)(
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig);
- //---------------------------------------------------------------------------
- bool __fastcall AutodetectProxyUrl(AnsiString & Proxy)
- {
- static HMODULE WinHTTP = NULL;
- static WINHTTPGETDEFAULTPROXYCONFIGURATION WinHttpGetDefaultProxyConfiguration = NULL;
- static WINHTTPGETIEPROXYCONFIGFORCURRENTUSER WinHttpGetIEProxyConfigForCurrentUser = NULL;
- bool Result = true;
- /* Under Win2K SP3, XP and 2003 (or at least Windows versions with
- WinHTTP 5.1 installed in some way, it officially shipped with the
- versions mentioned earlier) we can use WinHTTP AutoProxy support,
- which implements the Web Proxy Auto-Discovery (WPAD) protocol from
- an internet draft that expired in May 2001. Under older versions of
- Windows we have to use the WinINet InternetGetProxyInfo, however this
- consists of a ghastly set of kludges that were never meant to be
- exposed to the outside world (they were only crowbarred out of MS
- as part of the DoJ consent decree), and user experience with them is
- that they don't really work except in the one special way in which
- MS-internal code calls them. Since we don't know what this is, we
- use the WinHTTP functions instead */
- if (WinHTTP == NULL)
- {
- if ((WinHTTP = LoadLibrary("WinHTTP.dll")) == NULL)
- {
- Result = false;
- }
- else
- {
- WinHttpGetDefaultProxyConfiguration = (WINHTTPGETDEFAULTPROXYCONFIGURATION)
- GetProcAddress(WinHTTP, "WinHttpGetDefaultProxyConfiguration");
- WinHttpGetIEProxyConfigForCurrentUser = (WINHTTPGETIEPROXYCONFIGFORCURRENTUSER)
- GetProcAddress(WinHTTP, "WinHttpGetIEProxyConfigForCurrentUser");
- if ((WinHttpGetDefaultProxyConfiguration == NULL) ||
- (WinHttpGetIEProxyConfigForCurrentUser == NULL))
- {
- FreeLibrary(WinHTTP);
- Result = false;
- }
- }
- }
- if (Result)
- {
- Result = false;
- /* Forst we try for proxy info direct from the registry if
- it's available. */
- if (!Result)
- {
- WINHTTP_PROXY_INFO ProxyInfo;
- memset(&ProxyInfo, 0, sizeof(ProxyInfo));
- if ((WinHttpGetDefaultProxyConfiguration != NULL) &&
- WinHttpGetDefaultProxyConfiguration(&ProxyInfo))
- {
- if (ProxyInfo.lpszProxy != NULL)
- {
- Proxy = ProxyInfo.lpszProxy;
- GlobalFree(ProxyInfo.lpszProxy);
- Result = true;
- }
- if (ProxyInfo.lpszProxyBypass != NULL)
- {
- GlobalFree(ProxyInfo.lpszProxyBypass);
- }
- }
- }
- /* The next fallback is to get the proxy info from MSIE. This is also
- usually much quicker than WinHttpGetProxyForUrl(), although sometimes
- it seems to fall back to that, based on the longish delay involved.
- Another issue with this is that it won't work in a service process
- that isn't impersonating an interactive user (since there isn't a
- current user), but in that case we just fall back to
- WinHttpGetProxyForUrl() */
- if (!Result)
- {
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG IEProxyInfo;
- memset(&IEProxyInfo, 0, sizeof(IEProxyInfo));
- if ((WinHttpGetIEProxyConfigForCurrentUser != NULL) &&
- WinHttpGetIEProxyConfigForCurrentUser(&IEProxyInfo))
- {
- if (IEProxyInfo.lpszProxy != NULL)
- {
- Proxy = IEProxyInfo.lpszProxy;
- GlobalFree(IEProxyInfo.lpszProxy);
- Result = true;
- }
- if (IEProxyInfo.lpszAutoConfigUrl != NULL)
- {
- GlobalFree(IEProxyInfo.lpszAutoConfigUrl);
- }
- if (IEProxyInfo.lpszProxyBypass != NULL)
- {
- GlobalFree(IEProxyInfo.lpszProxyBypass);
- }
- }
- }
- // We can also use WinHttpGetProxyForUrl, but it is lengthy
- // See the source address of the code for example
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- //---------------------------------------------------------------------------
- class TWinHelpTester : public TInterfacedObject, public IWinHelpTester
- {
- public:
- virtual __fastcall ~TWinHelpTester();
- virtual bool __fastcall CanShowALink(const AnsiString ALink, const AnsiString FileName);
- virtual bool __fastcall CanShowTopic(const AnsiString Topic, const AnsiString FileName);
- virtual bool __fastcall CanShowContext(const int Context, const AnsiString FileName);
- virtual TStringList * __fastcall GetHelpStrings(const AnsiString ALink);
- virtual AnsiString __fastcall GetHelpPath();
- virtual AnsiString __fastcall GetDefaultHelpFile();
- IUNKNOWN
- };
- //---------------------------------------------------------------------------
- ICustomHelpViewer * CustomHelpViewer = NULL;
- _di_IHelpManager * PHelpManager = NULL;
- IUnknown * HelpManagerUnknown = NULL;
- TObjectList * ViewerList = NULL;
- ICustomHelpViewer * WinHelpViewer = NULL;
- //---------------------------------------------------------------------------
- static int __fastcall ViewerID(int Index)
- {
- // 8 is offset from THelpViewerNode to THelpViewerNode::FViewer
- return
- *reinterpret_cast<int *>(reinterpret_cast<char *>(ViewerList->Items[Index])
- + 8);
- }
- //---------------------------------------------------------------------------
- static void __fastcall InternalShutdown(int Index)
- {
- assert(PHelpManager != NULL);
- if (PHelpManager != NULL)
- {
- // override conflict of two Release() methods by getting
- // IHelpManager explicitly using operator *
- (**PHelpManager).Release(ViewerID(Index));
- // registration to help manager increases refcount by 2, but deregistration
- // by one only
- CustomHelpViewer->Release();
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall InitializeCustomHelp(ICustomHelpViewer * HelpViewer)
- {
- assert(PHelpManager == NULL);
- CustomHelpViewer = HelpViewer;
- // workaround
- // _di_IHelpManager cannot be instantiated due to either bug in compiler or
- // VCL code
- PHelpManager = (_di_IHelpManager*)malloc(sizeof(_di_IHelpManager));
- // our own reference
- CustomHelpViewer->AddRef();
- RegisterViewer(CustomHelpViewer, *PHelpManager);
- HelpManagerUnknown = dynamic_cast<IUnknown *>(&**PHelpManager);
- // 40 is offset from IHelpManager to THelpManager
- // 16 is offset from THelpManager to THelpManager::FViewerList
- ViewerList =
- *reinterpret_cast<TObjectList **>(reinterpret_cast<char *>(&**PHelpManager)
- - 40 + 16);
- assert(ViewerList->Count == 2);
- // gross hack
- // Due to major bugs in VCL help system, unregister winhelp at all.
- // To do this we must call RegisterViewer first to get HelpManager.
- // Due to another bug, viewers must be unregistred in order reversed to
- // registration order, so we must unregister our help viewer first
- // and register it again at the end
- InternalShutdown(1);
- assert(ViewerList->Count == 1);
- int WinHelpViewerID = ViewerID(0);
- // 4 is offset from THelpViewerNode to THelpViewerNode::FViewer
- WinHelpViewer =
- *reinterpret_cast<_di_ICustomHelpViewer *>(reinterpret_cast<char *>(ViewerList->Items[0])
- + 4);
- // our reference
- // we cannot release win help viewer completelly here as finalization code of
- // WinHelpViewer expect it to exist
- WinHelpViewer->AddRef();
- (**PHelpManager).Release(WinHelpViewerID);
- // remove forgoten 3 references of manager
- WinHelpViewer->Release();
- WinHelpViewer->Release();
- WinHelpViewer->Release();
- assert(ViewerList->Count == 0);
- // this clears reference to manager in TWinHelpViewer::FHelpManager,
- // preventing call to TWinHelpViewer::InternalShutdown from finalization code
- // of WinHelpViewer
- WinHelpViewer->ShutDown();
- RegisterViewer(CustomHelpViewer, *PHelpManager);
- // we've got second reference to the same pointer here, release it
- HelpManagerUnknown->Release();
- assert(ViewerList->Count == 1);
- // now when winhelp is not registered, the tester is not used anyway
- // for any real work, but we use it as a hook to be called after
- // finalization of WinHelpViewer (see its finalization section)
- WinHelpTester = new TWinHelpTester();
- }
- //---------------------------------------------------------------------------
- void __fastcall FinalizeCustomHelp()
- {
- if (CustomHelpViewer != NULL)
- {
- // unregister ourselves to release both references
- InternalShutdown(0);
- // our own reference
- CustomHelpViewer->Release();
- }
- if (PHelpManager != NULL)
- {
- assert(ViewerList->Count == 0);
- // our reference
- HelpManagerUnknown->Release();
- free(PHelpManager);
- PHelpManager = NULL;
- HelpManagerUnknown = NULL;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall CleanUpWinHelp()
- {
- // WinHelpViewer finalization code should have been called by now already,
- // so we can safely remove the last reference to destroy it
- assert(WinHelpViewer != NULL);
- WinHelpViewer->Release();
- }
- //---------------------------------------------------------------------------
- //---------------------------------------------------------------------------
- __fastcall TWinHelpTester::~TWinHelpTester()
- {
- CleanUpWinHelp();
- }
- //---------------------------------------------------------------------------
- bool __fastcall TWinHelpTester::CanShowALink(const AnsiString ALink,
- const AnsiString FileName)
- {
- assert(false);
- return !Application->HelpFile.IsEmpty();
- }
- //---------------------------------------------------------------------------
- bool __fastcall TWinHelpTester::CanShowTopic(const AnsiString Topic,
- const AnsiString FileName)
- {
- assert(false);
- return !Application->HelpFile.IsEmpty();
- }
- //---------------------------------------------------------------------------
- bool __fastcall TWinHelpTester::CanShowContext(const int /*Context*/,
- const AnsiString FileName)
- {
- assert(false);
- return !Application->HelpFile.IsEmpty();
- }
- //---------------------------------------------------------------------------
- TStringList * __fastcall TWinHelpTester::GetHelpStrings(const AnsiString ALink)
- {
- assert(false);
- TStringList * Result = new TStringList();
- Result->Add(ViewerName + ": " + ALink);
- return Result;
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall TWinHelpTester::GetHelpPath()
- {
- assert(false);
- // never called on windows anyway
- return ExtractFilePath(Application->HelpFile);
- }
- //---------------------------------------------------------------------------
- AnsiString __fastcall TWinHelpTester::GetDefaultHelpFile()
- {
- assert(false);
- return Application->HelpFile;
- }
|