| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681 |
- //---------------------------------------------------------------------------
- #include <vcl.h>
- #pragma hdrstop
- #include "WinInterface.h"
- #include "VCLCommon.h"
- #include <Common.h>
- #include <TextsWin.h>
- #include <RemoteFiles.h>
- #include <GUITools.h>
- #include <Tools.h>
- #include <FileCtrl.hpp>
- #include <PathLabel.hpp>
- #include <PasTools.hpp>
- #include <Vcl.Imaging.pngimage.hpp>
- #include <Math.hpp>
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- //---------------------------------------------------------------------------
- void __fastcall AdjustListColumnsWidth(TListView * ListView)
- {
- int OriginalWidth, NewWidth, i, CWidth, LastResizible;
- OriginalWidth = 0;
- LastResizible = -1;
- for (i = 0; i < ListView->Columns->Count; i++)
- {
- OriginalWidth += ListView->Columns->Items[i]->Width;
- if (ListView->Columns->Items[i]->Tag == 0)
- {
- LastResizible = i;
- }
- }
- assert(LastResizible >= 0);
- int RowCount = ListView->Items->Count;
- NewWidth = 0;
- CWidth = ListView->ClientWidth;
- if ((ListView->VisibleRowCount < RowCount) &&
- (ListView->Width - ListView->ClientWidth < GetSystemMetrics(SM_CXVSCROLL)))
- {
- CWidth -= GetSystemMetrics(SM_CXVSCROLL);
- }
- for (i = 0; i < ListView->Columns->Count; i++)
- {
- if (i != LastResizible)
- {
- if (ListView->Columns->Items[i]->Tag == 0)
- {
- ListView->Columns->Items[i]->Width =
- (CWidth * ListView->Columns->Items[i]->Width) / OriginalWidth;
- }
- NewWidth += ListView->Columns->Items[i]->Width;
- }
- }
- ListView->Columns->Items[LastResizible]->Width = CWidth-NewWidth;
- }
- //---------------------------------------------------------------------------
- static void __fastcall SetParentColor(TControl * Control)
- {
- TColor Color = clBtnFace;
- ((TEdit*)Control)->Color = Color;
- }
- //---------------------------------------------------------------------------
- void __fastcall EnableControl(TControl * Control, bool Enable)
- {
- if (Control->Enabled != Enable)
- {
- TWinControl * WinControl = dynamic_cast<TWinControl *>(Control);
- if ((WinControl != NULL) &&
- (WinControl->ControlCount > 0))
- {
- for (int Index = 0; Index < WinControl->ControlCount; Index++)
- {
- EnableControl(WinControl->Controls[Index], Enable);
- }
- }
- Control->Enabled = Enable;
- }
- if ((dynamic_cast<TCustomEdit *>(Control) != NULL) ||
- (dynamic_cast<TCustomComboBox *>(Control) != NULL) ||
- (dynamic_cast<TCustomListView *>(Control) != NULL) ||
- (dynamic_cast<TTreeView *>(Control) != NULL))
- {
- if (Enable)
- {
- ((TEdit*)Control)->Color = clWindow;
- }
- else
- {
- ((TEdit*)Control)->Color = clBtnFace;
- }
- }
- };
- //---------------------------------------------------------------------------
- void __fastcall ReadOnlyControl(TControl * Control, bool ReadOnly)
- {
- if (dynamic_cast<TCustomEdit *>(Control) != NULL)
- {
- ((TEdit*)Control)->ReadOnly = ReadOnly;
- TMemo * Memo = dynamic_cast<TMemo *>(Control);
- if (ReadOnly)
- {
- SetParentColor(Control);
- if (Memo != NULL)
- {
- // Is true by default and makes the control swallow not only
- // returns but also escapes
- Memo->WantReturns = false;
- }
- }
- else
- {
- ((TEdit*)Control)->Color = clWindow;
- // not supported atm, we need to persist previous value of WantReturns
- assert(Memo == NULL);
- }
- }
- else if ((dynamic_cast<TCustomComboBox *>(Control) != NULL) ||
- (dynamic_cast<TCustomTreeView *>(Control) != NULL))
- {
- EnableControl(Control, !ReadOnly);
- }
- else
- {
- assert(false);
- }
- }
- //---------------------------------------------------------------------------
- struct TSavedSystemSettings
- {
- TCustomForm * Form;
- UnicodeString FontName;
- bool Flipped;
- TWndMethod OldWndProc;
- };
- //---------------------------------------------------------------------------
- class TPublicControl : public TWinControl
- {
- friend TWndMethod __fastcall ControlWndProc(TWinControl * Control);
- };
- //---------------------------------------------------------------------------
- TWndMethod __fastcall ControlWndProc(TWinControl * Control)
- {
- TPublicControl * PublicControl = static_cast<TPublicControl *>(Control);
- return &PublicControl->WndProc;
- }
- //---------------------------------------------------------------------------
- static Forms::TMonitor * LastMonitor = NULL;
- //---------------------------------------------------------------------------
- inline void __fastcall DoFormWindowProc(TCustomForm * Form, TWndMethod WndProc,
- TMessage & Message)
- {
- if ((Message.Msg == WM_SYSCOMMAND) &&
- (Message.WParam == SC_CONTEXTHELP))
- {
- InvokeHelp(Form->ActiveControl);
- Message.Result = 1;
- }
- else if (Message.Msg == CM_SHOWINGCHANGED)
- {
- TForm * AForm = dynamic_cast<TForm *>(Form);
- assert(AForm != NULL);
- if ((Application->MainForm == Form) ||
- // this particularly happens if error occurs while main
- // window is being shown (e.g. non existent local directory when opening
- // explorer)
- ((Application->MainForm != NULL) && !Application->MainForm->Visible))
- {
- if (Form->Showing)
- {
- SendMessage(Form->Handle, WM_SETICON, ICON_BIG, reinterpret_cast<long>(Application->Icon->Handle));
- }
- if (!Form->Showing)
- {
- // when closing main form, remember its monitor,
- // so that the next form is shown on the same one
- LastMonitor = Form->Monitor;
- }
- else if ((LastMonitor != NULL) && (LastMonitor != Form->Monitor) &&
- Form->Showing)
- {
- // would actually always be poScreenCenter, see _SafeFormCreate
- if ((AForm->Position == poMainFormCenter) ||
- (AForm->Position == poOwnerFormCenter) ||
- (AForm->Position == poScreenCenter))
- {
- // this would typically be an authentication dialog,
- // but it may as well be an message box
- // taken from TCustomForm::SetWindowToMonitor
- AForm->SetBounds(LastMonitor->Left + ((LastMonitor->Width - AForm->Width) / 2),
- LastMonitor->Top + ((LastMonitor->Height - AForm->Height) / 2),
- AForm->Width, AForm->Height);
- AForm->Position = poDesigned;
- }
- else if ((AForm->Position != poDesigned) &&
- (AForm->Position != poDefaultPosOnly))
- {
- // we do not expect any other positioning
- assert(false);
- }
- }
- else
- {
- TForm * AForm = dynamic_cast<TForm *>(Form);
- assert(AForm != NULL);
- // otherwise it would not get centered
- if ((AForm->Position == poMainFormCenter) ||
- (AForm->Position == poOwnerFormCenter))
- {
- AForm->Position = poScreenCenter;
- }
- }
- }
- bool WasFormCenter =
- (AForm->Position == poMainFormCenter) ||
- (AForm->Position == poOwnerFormCenter);
- WndProc(Message);
- // Make sure dialogs are shown on-screen even if center of the main window
- // is off-screen. Occurs e.g. if you move the main window so that
- // only window title is visible above taksbar.
- if (Form->Showing && WasFormCenter && (AForm->Position == poDesigned))
- {
- TRect Rect;
- // Reading Form.Left/Form.Top instead here does not work, likely due to some
- // bug, when querying TProgressForm opened from TEditorForm (reloading remote file)
- GetWindowRect(Form->Handle, &Rect);
- int Left = Rect.Left;
- int Top = Rect.Top;
- TRect WorkArea = AForm->Monitor->WorkareaRect;
- if (Left + Rect.Width() > WorkArea.Right)
- {
- Left = WorkArea.Right - Rect.Width();
- }
- if (Left < WorkArea.Left)
- {
- Left = WorkArea.Left;
- }
- if (Top + Rect.Height() > WorkArea.Bottom)
- {
- Top = WorkArea.Bottom - Rect.Height();
- }
- if (Top < WorkArea.Top)
- {
- Top = WorkArea.Top;
- }
- if ((Left != Rect.Left) ||
- (Top != Rect.Top))
- {
- SetWindowPos(Form->Handle, 0, Left, Top, Rect.Width(), Rect.Height(),
- SWP_NOZORDER + SWP_NOACTIVATE);
- }
- }
- }
- else
- {
- WndProc(Message);
- }
- }
- //---------------------------------------------------------------------------
- static void __fastcall FormWindowProc(void * Data, TMessage & Message)
- {
- TCustomForm * Form = static_cast<TCustomForm *>(Data);
- DoFormWindowProc(Form, ControlWndProc(Form), Message);
- }
- //---------------------------------------------------------------------------
- static void __fastcall FormWindowProcEx(void * Data, TMessage & Message)
- {
- TSavedSystemSettings * SSettings = static_cast<TSavedSystemSettings *>(Data);
- DoFormWindowProc(SSettings->Form, SSettings->OldWndProc, Message);
- }
- //---------------------------------------------------------------------------
- void __fastcall InitializeSystemSettings()
- {
- }
- //---------------------------------------------------------------------------
- void __fastcall FinalizeSystemSettings()
- {
- }
- //---------------------------------------------------------------------------
- #ifdef _DEBUG
- void __fastcall VerifyControl(TControl * Control)
- {
- // If at this time the control has allocated persistence data that are used
- // for delayed handle recreation, we are at potential risk, as the future
- // de-persistence may overwrite meanwhile changed data.
- // For instance it may happen with list view that DPI scaling gets lost.
- // This for example happens when the list view has both design time
- // ReadOnly = true and some items set. We cannot usually explicitly
- // check for the presence of items as while the listview does not have
- // a handle allocated, item count querying does not work
- // (see also a check below)
- assert(!ControlHasRecreationPersistenceData(Control));
- TCustomListView * ListView = dynamic_cast<TCustomListView *>(Control);
- if (ListView != NULL)
- {
- // As of now the HandleAllocated check is pointless as
- // ListView->Items->Count returns 0 when the handle is not allocated yet.
- // But we want to know if the implementation ever changes to allocate the handle
- // on the call. Because we do not want to allocate a handle here as
- // that would change the debug mode behaviour from release behaviour,
- // possibly hiding away some problems.
- assert(!ListView->HandleAllocated() || (ListView->Items->Count == 0));
- }
- }
- #endif
- //---------------------------------------------------------------------------
- void __fastcall ApplySystemSettingsOnControl(TControl * Control)
- {
- #ifdef _DEBUG
- VerifyControl(Control);
- #endif
- // WORKAROUND
- // VCL does not scale status par panels (while for instance it does
- // scale list view headers). Remove this if they ever "fix" this.
- // For TBX status bars, this is implemented in TTBXCustomStatusBar.ChangeScale
- TStatusBar * StatusBar = dynamic_cast<TStatusBar *>(Control);
- if (StatusBar != NULL)
- {
- for (int Index = 0; Index < StatusBar->Panels->Count; Index++)
- {
- TStatusPanel * Panel = StatusBar->Panels->Items[Index];
- Panel->Width = ScaleByTextHeight(StatusBar, Panel->Width);
- }
- }
- TWinControl * WinControl = dynamic_cast<TWinControl *>(Control);
- if (WinControl != NULL)
- {
- for (int Index = 0; Index < WinControl->ControlCount; Index++)
- {
- ApplySystemSettingsOnControl(WinControl->Controls[Index]);
- }
- }
- }
- //---------------------------------------------------------------------------
- // Settings that must be set as soon as possible.
- void __fastcall UseSystemSettingsPre(TCustomForm * Control, void ** Settings)
- {
- LocalSystemSettings(Control);
- TWndMethod WindowProc;
- if (Settings)
- {
- TSavedSystemSettings * SSettings;
- SSettings = new TSavedSystemSettings();
- *Settings = static_cast<void*>(SSettings);
- SSettings->Form = Control;
- SSettings->FontName = Control->Font->Name;
- SSettings->OldWndProc = Control->WindowProc;
- ((TMethod*)&WindowProc)->Data = SSettings;
- ((TMethod*)&WindowProc)->Code = FormWindowProcEx;
- }
- else
- {
- ((TMethod*)&WindowProc)->Data = Control;
- ((TMethod*)&WindowProc)->Code = FormWindowProc;
- }
- Control->WindowProc = WindowProc;
- if (Control->HelpKeyword.IsEmpty())
- {
- // temporary help keyword to enable F1 key in all forms
- Control->HelpKeyword = L"start";
- }
- ApplySystemSettingsOnControl(Control);
- };
- //---------------------------------------------------------------------------
- // Settings that must be set only after whole form is constructed
- void __fastcall UseSystemSettingsPost(TCustomForm * Control, void * Settings)
- {
- bool Flip;
- UnicodeString FlipStr = LoadStr(FLIP_CHILDREN);
- Flip = !FlipStr.IsEmpty() && static_cast<bool>(StrToInt(FlipStr));
- if (Settings != NULL)
- {
- static_cast<TSavedSystemSettings*>(Settings)->Flipped = Flip;
- }
- if (Flip)
- {
- Control->FlipChildren(true);
- }
- ResetSystemSettings(Control);
- };
- //---------------------------------------------------------------------------
- void __fastcall UseSystemSettings(TCustomForm * Control, void ** Settings)
- {
- UseSystemSettingsPre(Control, Settings);
- UseSystemSettingsPost(Control, (Settings != NULL) ? *Settings : NULL);
- };
- //---------------------------------------------------------------------------
- void __fastcall ResetSystemSettings(TCustomForm * /*Control*/)
- {
- // noop
- }
- //---------------------------------------------------------------------------
- void __fastcall DeleteSystemSettings(TCustomForm * Control, void * Settings)
- {
- assert(Settings);
- TSavedSystemSettings * SSettings = static_cast<TSavedSystemSettings *>(Settings);
- Control->WindowProc = SSettings->OldWndProc;
- delete SSettings;
- }
- //---------------------------------------------------------------------------
- void __fastcall RevokeSystemSettings(TCustomForm * Control, void * Settings)
- {
- assert(Settings);
- TSavedSystemSettings* SSettings = static_cast<TSavedSystemSettings*>(Settings);
- if (SSettings->Flipped)
- {
- Control->FlipChildren(true);
- }
- DeleteSystemSettings(Control, Settings);
- };
- //---------------------------------------------------------------------------
- class TPublicForm : public TForm
- {
- friend void __fastcall ShowAsModal(TForm * Form, void *& Storage);
- friend void __fastcall HideAsModal(TForm * Form, void *& Storage);
- };
- //---------------------------------------------------------------------------
- struct TShowAsModalStorage
- {
- void * FocusWindowList;
- HWND FocusActiveWindow;
- TFocusState FocusState;
- };
- //---------------------------------------------------------------------------
- void __fastcall ShowAsModal(TForm * Form, void *& Storage)
- {
- SetCorrectFormParent(Form);
- CancelDrag();
- if (GetCapture() != 0) SendMessage(GetCapture(), WM_CANCELMODE, 0, 0);
- ReleaseCapture();
- (static_cast<TPublicForm*>(Form))->FFormState << fsModal;
- TShowAsModalStorage * AStorage = new TShowAsModalStorage;
- AStorage->FocusActiveWindow = GetActiveWindow();
- AStorage->FocusState = SaveFocusState();
- Screen->SaveFocusedList->Insert(0, Screen->FocusedForm);
- Screen->FocusedForm = Form;
- AStorage->FocusWindowList = DisableTaskWindows(0);
- Form->Show();
- SendMessage(Form->Handle, CM_ACTIVATE, 0, 0);
- Storage = AStorage;
- }
- //---------------------------------------------------------------------------
- void __fastcall HideAsModal(TForm * Form, void *& Storage)
- {
- assert((static_cast<TPublicForm*>(Form))->FFormState.Contains(fsModal));
- TShowAsModalStorage * AStorage = static_cast<TShowAsModalStorage *>(Storage);
- Storage = NULL;
- SendMessage(Form->Handle, CM_DEACTIVATE, 0, 0);
- if (GetActiveWindow() != Form->Handle)
- {
- AStorage->FocusActiveWindow = 0;
- }
- Form->Hide();
- EnableTaskWindows(AStorage->FocusWindowList);
- if (Screen->SaveFocusedList->Count > 0)
- {
- Screen->FocusedForm = static_cast<TCustomForm *>(Screen->SaveFocusedList->First());
- Screen->SaveFocusedList->Remove(Screen->FocusedForm);
- }
- else
- {
- Screen->FocusedForm = NULL;
- }
- if (AStorage->FocusActiveWindow != 0)
- {
- SetActiveWindow(AStorage->FocusActiveWindow);
- }
- RestoreFocusState(AStorage->FocusState);
- (static_cast<TPublicForm*>(Form))->FFormState >> fsModal;
- delete AStorage;
- }
- //---------------------------------------------------------------------------
- void __fastcall ReleaseAsModal(TForm * Form, void *& Storage)
- {
- if (Storage != NULL)
- {
- HideAsModal(Form, Storage);
- }
- }
- //---------------------------------------------------------------------------
- bool __fastcall SelectDirectory(UnicodeString & Path, const UnicodeString Prompt,
- bool PreserveFileName)
- {
- bool Result;
- unsigned int ErrorMode;
- ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
- try
- {
- UnicodeString Directory;
- UnicodeString FileName;
- if (!PreserveFileName || DirectoryExists(Path))
- {
- Directory = Path;
- }
- else
- {
- Directory = ExtractFilePath(Path);
- FileName = ExtractFileName(Path);
- }
- Result = SelectDirectory(Prompt, L"", Directory);
- if (Result)
- {
- Path = Directory;
- if (!FileName.IsEmpty())
- {
- Path = IncludeTrailingBackslash(Path) + FileName;
- }
- }
- }
- __finally
- {
- SetErrorMode(ErrorMode);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- bool __fastcall ListViewAnyChecked(TListView * ListView, bool Checked)
- {
- bool AnyChecked = false;
- for (int Index = 0; Index < ListView->Items->Count; Index++)
- {
- if (ListView->Items->Item[Index]->Checked == Checked)
- {
- AnyChecked = true;
- break;
- }
- }
- return AnyChecked;
- }
- //---------------------------------------------------------------------------
- void __fastcall ListViewCheckAll(TListView * ListView,
- TListViewCheckAll CheckAll)
- {
- bool Check;
- if (CheckAll == caToggle)
- {
- Check = ListViewAnyChecked(ListView, false);
- }
- else
- {
- Check = (CheckAll == caCheck);
- }
- for (int Index = 0; Index < ListView->Items->Count; Index++)
- {
- ListView->Items->Item[Index]->Checked = Check;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall ComboAutoSwitchInitialize(TComboBox * ComboBox)
- {
- int PrevIndex = ComboBox->ItemIndex;
- ComboBox->Items->BeginUpdate();
- try
- {
- ComboBox->Clear();
- ComboBox->Items->Add(LoadStr(AUTO_SWITCH_AUTO));
- ComboBox->Items->Add(LoadStr(AUTO_SWITCH_OFF));
- ComboBox->Items->Add(LoadStr(AUTO_SWITCH_ON));
- }
- __finally
- {
- ComboBox->Items->EndUpdate();
- }
- assert(PrevIndex < ComboBox->Items->Count);
- ComboBox->ItemIndex = PrevIndex;
- }
- //---------------------------------------------------------------------------
- void __fastcall ComboAutoSwitchLoad(TComboBox * ComboBox, TAutoSwitch Value)
- {
- ComboBox->ItemIndex = 2 - Value;
- if (ComboBox->ItemIndex < 0)
- {
- ComboBox->ItemIndex = 0;
- }
- }
- //---------------------------------------------------------------------------
- TAutoSwitch __fastcall ComboAutoSwitchSave(TComboBox * ComboBox)
- {
- return (TAutoSwitch)(2 - ComboBox->ItemIndex);
- }
- //---------------------------------------------------------------------------
- void __fastcall CheckBoxAutoSwitchLoad(TCheckBox * CheckBox, TAutoSwitch Value)
- {
- switch (Value)
- {
- case asOn:
- CheckBox->State = cbChecked;
- break;
- case asOff:
- CheckBox->State = cbUnchecked;
- break;
- default:
- CheckBox->State = cbGrayed;
- break;
- }
- }
- //---------------------------------------------------------------------------
- TAutoSwitch __fastcall CheckBoxAutoSwitchSave(TCheckBox * CheckBox)
- {
- switch (CheckBox->State)
- {
- case cbChecked:
- return asOn;
- case cbUnchecked:
- return asOff;
- default:
- return asAuto;
- }
- }
- //---------------------------------------------------------------------------
- static const wchar_t PathWordDelimiters[] = L"\\/ ;,.";
- //---------------------------------------------------------------------------
- static bool IsPathWordDelimiter(wchar_t Ch)
- {
- return (wcschr(PathWordDelimiters, Ch) != NULL);
- }
- //---------------------------------------------------------------------------
- // Windows algorithm is as follows (tested on W2k):
- // right:
- // is_delimiter(current)
- // false:
- // right(left(current) + 1)
- // true:
- // right(right(current) + 1)
- // left:
- // right(left(current) + 1)
- int CALLBACK PathWordBreakProc(wchar_t * Ch, int Current, int Len, int Code)
- {
- int Result;
- UnicodeString ACh(Ch, Len);
- if (Code == WB_ISDELIMITER)
- {
- // we return negacy of what WinAPI docs says
- Result = !IsPathWordDelimiter(ACh[Current + 1]);
- }
- else if (Code == WB_LEFT)
- {
- // skip consecutive delimiters
- while ((Current > 0) &&
- IsPathWordDelimiter(ACh[Current]))
- {
- Current--;
- }
- Result = ACh.SubString(1, Current - 1).LastDelimiter(PathWordDelimiters);
- }
- else if (Code == WB_RIGHT)
- {
- if (Current == 0)
- {
- // will be called again with Current == 1
- Result = 0;
- }
- else
- {
- const wchar_t * P = wcspbrk(ACh.c_str() + Current - 1, PathWordDelimiters);
- if (P == NULL)
- {
- Result = Len;
- }
- else
- {
- Result = P - ACh.c_str() + 1;
- // skip consecutive delimiters
- while ((Result < Len) &&
- IsPathWordDelimiter(ACh[Result + 1]))
- {
- Result++;
- }
- }
- }
- }
- else
- {
- assert(false);
- Result = 0;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- class TPublicCustomCombo : public TCustomCombo
- {
- friend void __fastcall InstallPathWordBreakProc(TWinControl * Control);
- };
- //---------------------------------------------------------------------------
- void __fastcall InstallPathWordBreakProc(TWinControl * Control)
- {
- // Since we are setting Application->ModalPopupMode = pmAuto,
- // this has to be called from OnShow, not from constructor anymore,
- // to have any effect
- HWND Wnd;
- if (dynamic_cast<TCustomCombo*>(Control) != NULL)
- {
- TPublicCustomCombo * Combo =
- static_cast<TPublicCustomCombo *>(dynamic_cast<TCustomCombo *>(Control));
- Combo->HandleNeeded();
- Wnd = Combo->EditHandle;
- }
- else
- {
- Wnd = Control->Handle;
- }
- SendMessage(Wnd, EM_SETWORDBREAKPROC, 0, (LPARAM)(EDITWORDBREAKPROC)PathWordBreakProc);
- }
- //---------------------------------------------------------------------------
- static void __fastcall RemoveHiddenControlsFromOrder(TControl ** ControlsOrder, int & Count)
- {
- int Shift = 0;
- for (int Index = 0; Index < Count; Index++)
- {
- if (ControlsOrder[Index]->Visible)
- {
- ControlsOrder[Index - Shift] = ControlsOrder[Index];
- }
- else
- {
- Shift++;
- }
- }
- Count -= Shift;
- }
- //---------------------------------------------------------------------------
- void __fastcall SetVerticalControlsOrder(TControl ** ControlsOrder, int Count)
- {
- RemoveHiddenControlsFromOrder(ControlsOrder, Count);
- if (Count > 0)
- {
- TWinControl * CommonParent = ControlsOrder[0]->Parent;
- CommonParent->DisableAlign();
- try
- {
- int Top = 0;
- for (int Index = 0; Index < Count; Index++)
- {
- assert(ControlsOrder[Index]->Parent == CommonParent);
- if ((Index == 0) || (Top > ControlsOrder[Index]->Top))
- {
- Top = ControlsOrder[Index]->Top;
- }
- }
- for (int Index = 0; Index < Count; Index++)
- {
- TControl * Control = ControlsOrder[Index];
- Control->Top = Top;
- if (((Control->Align == alTop) || (Control->Align == alBottom)) ||
- ((Index == Count - 1) || (ControlsOrder[Index + 1]->Align == alBottom)))
- {
- Top += Control->Height;
- }
- }
- }
- __finally
- {
- CommonParent->EnableAlign();
- }
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall SetHorizontalControlsOrder(TControl ** ControlsOrder, int Count)
- {
- RemoveHiddenControlsFromOrder(ControlsOrder, Count);
- if (Count > 0)
- {
- TWinControl * CommonParent = ControlsOrder[0]->Parent;
- CommonParent->DisableAlign();
- try
- {
- int Left = 0;
- for (int Index = 0; Index < Count; Index++)
- {
- assert(ControlsOrder[Index]->Parent == CommonParent);
- if ((Index == 0) || (Left > ControlsOrder[Index]->Left))
- {
- Left = ControlsOrder[Index]->Left;
- }
- }
- for (int Index = 0; Index < Count; Index++)
- {
- TControl * Control = ControlsOrder[Index];
- Control->Left = Left;
- if (((Control->Align == alLeft) || (Control->Align == alRight)) ||
- ((Index == Count - 1) || (ControlsOrder[Index + 1]->Align == alRight)))
- {
- Left += Control->Width;
- }
- // vertical alignment has priority, so alBottom-aligned controls start
- // at the very left, even if there are any alLeft/alRight controls.
- // for the reason this code is not necessary in SetVerticalControlsOrder.
- // we could exit the loop as well here.
- if ((Index == Count - 1) || (ControlsOrder[Index + 1]->Align == alBottom))
- {
- Left = 0;
- }
- }
- }
- __finally
- {
- CommonParent->EnableAlign();
- }
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall MakeNextInTabOrder(TWinControl * Control, TWinControl * After)
- {
- if (After->TabOrder > Control->TabOrder)
- {
- After->TabOrder = Control->TabOrder;
- }
- else if (After->TabOrder < Control->TabOrder - 1)
- {
- After->TabOrder = static_cast<TTabOrder>(Control->TabOrder - 1);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall CutFormToDesktop(TForm * Form)
- {
- assert(Form->Monitor != NULL);
- TRect Workarea = Form->Monitor->WorkareaRect;
- if (Form->Top + Form->Height > Workarea.Bottom)
- {
- Form->Height = Workarea.Bottom - Form->Top;
- }
- if (Form->Left + Form->Width >= Workarea.Right)
- {
- Form->Width = Workarea.Right - Form->Left;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall UpdateFormPosition(TCustomForm * Form, TPosition Position)
- {
- if ((Position == poScreenCenter) ||
- (Position == poOwnerFormCenter) ||
- (Position == poMainFormCenter))
- {
- TCustomForm * CenterForm = NULL;
- if ((Position == poOwnerFormCenter) ||
- (Position == poMainFormCenter))
- {
- CenterForm = Application->MainForm;
- if ((Position == poOwnerFormCenter) &&
- (dynamic_cast<TCustomForm*>(Form->Owner) != NULL))
- {
- CenterForm = dynamic_cast<TCustomForm*>(Form->Owner);
- }
- }
- TRect Bounds = Form->BoundsRect;
- int X, Y;
- if (CenterForm != NULL)
- {
- X = ((((TForm *)CenterForm)->Width - Bounds.Width()) / 2) +
- ((TForm *)CenterForm)->Left;
- Y = ((((TForm *)CenterForm)->Height - Bounds.Height()) / 2) +
- ((TForm *)CenterForm)->Top;
- }
- else
- {
- X = (Form->Monitor->Width - Bounds.Width()) / 2;
- Y = (Form->Monitor->Height - Bounds.Height()) / 2;
- }
- if (X < 0)
- {
- X = 0;
- }
- if (Y < 0)
- {
- Y = 0;
- }
- Form->SetBounds(X, Y, Bounds.Width(), Bounds.Height());
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall ResizeForm(TCustomForm * Form, int Width, int Height)
- {
- // This has to be called only after DoFormWindowProc(CM_SHOWINGCHANGED),
- // so that a correct monitor is considered.
- // Note that we cannot use LastMonitor(), as ResizeForm is also called from
- // TConsoleDialog::DoAdjustWindow, where we need to use the actual monitor
- // (in case user moves the console window to a different monitor,
- // than where a main window is [no matter how unlikely that is])
- TRect WorkareaRect = Form->Monitor->WorkareaRect;
- if (Height > WorkareaRect.Height())
- {
- Height = WorkareaRect.Height();
- }
- if (Width > WorkareaRect.Width())
- {
- Width = WorkareaRect.Width();
- }
- if (Height < Form->Constraints->MinHeight)
- {
- Height = Form->Constraints->MinHeight;
- }
- if (Width < Form->Constraints->MinWidth)
- {
- Width = Form->Constraints->MinWidth;
- }
- TRect Bounds = Form->BoundsRect;
- int Top = Bounds.Top + ((Bounds.Height() - Height) / 2);
- int Left = Bounds.Left + ((Bounds.Width() - Width) / 2);
- if (Top + Height > WorkareaRect.Bottom)
- {
- Top = WorkareaRect.Bottom - Height;
- }
- if (Left + Width >= WorkareaRect.Right)
- {
- Left = WorkareaRect.Right - Width;
- }
- // WorkareaRect.Left is not 0, when secondary monitor is placed left of primary one.
- // Similarly for WorkareaRect.Top.
- if (Top < WorkareaRect.Top)
- {
- Top = WorkareaRect.Top;
- }
- if (Left < WorkareaRect.Left)
- {
- Left = WorkareaRect.Left;
- }
- Form->SetBounds(Left, Top, Width, Height);
- Bounds = Form->BoundsRect;
- // due to constraints, form can remain larger, make sure it is centered although
- Left = Bounds.Left + ((Width - Bounds.Width()) / 2);
- Top = Bounds.Top + ((Height - Bounds.Height()) / 2);
- Form->SetBounds(Left, Top, Width, Height);
- }
- //---------------------------------------------------------------------------
- TComponent * __fastcall GetFormOwner()
- {
- if (Screen->ActiveForm != NULL)
- {
- return Screen->ActiveForm;
- }
- else
- {
- return Application;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall SetCorrectFormParent(TForm * /*Form*/)
- {
- // noop
- // remove
- }
- //---------------------------------------------------------------------------
- void __fastcall InvokeHelp(TWinControl * Control)
- {
- assert(Control != NULL);
- HELPINFO HelpInfo;
- HelpInfo.cbSize = sizeof(HelpInfo);
- HelpInfo.iContextType = HELPINFO_WINDOW;
- HelpInfo.iCtrlId = 0;
- HelpInfo.hItemHandle = Control->Handle;
- HelpInfo.dwContextId = 0;
- HelpInfo.MousePos.x = 0;
- HelpInfo.MousePos.y = 0;
- SendMessage(Control->Handle, WM_HELP, NULL, reinterpret_cast<long>(&HelpInfo));
- }
- //---------------------------------------------------------------------------
- //---------------------------------------------------------------------------
- static void __fastcall FocusableLabelCanvas(TStaticText * StaticText,
- TControlCanvas ** ACanvas, TRect & R)
- {
- TControlCanvas * Canvas = new TControlCanvas();
- try
- {
- Canvas->Control = StaticText;
- R = StaticText->ClientRect;
- UnicodeString Caption = StaticText->Caption;
- bool AccelChar = false;
- if (StaticText->ShowAccelChar)
- {
- Caption = StripHotkey(Caption);
- AccelChar = (Caption != StaticText->Caption);
- }
- TSize TextSize = Canvas->TextExtent(Caption);
- assert(StaticText->BorderStyle == sbsNone); // not taken into account
- if (AccelChar)
- {
- TextSize.cy += 2;
- }
- R.Bottom = R.Top + TextSize.cy;
- switch (StaticText->Alignment)
- {
- case taLeftJustify:
- R.Right = R.Left + TextSize.cx;
- break;
- case taRightJustify:
- R.Left = Max(0, R.Right - TextSize.cx);
- break;
- case taCenter:
- {
- FAIL; // not used branch, possibly untested
- int Diff = R.Width() - TextSize.cx;
- R.Left += Diff / 2;
- R.Right -= Diff - (Diff / 2);
- }
- break;
- }
- }
- __finally
- {
- if (ACanvas == NULL)
- {
- delete Canvas;
- }
- }
- if (ACanvas != NULL)
- {
- *ACanvas = Canvas;
- }
- }
- //---------------------------------------------------------------------------
- static void __fastcall FocusableLabelWindowProc(void * Data, TMessage & Message,
- bool & Clicked)
- {
- Clicked = false;
- TStaticText * StaticText = static_cast<TStaticText *>(Data);
- if (Message.Msg == WM_LBUTTONDOWN)
- {
- StaticText->SetFocus();
- // in case the action takes long, make sure focus is shown immediatelly
- UpdateWindow(StaticText->Handle);
- Clicked = true;
- Message.Result = 1;
- }
- else if (Message.Msg == WM_RBUTTONDOWN)
- {
- StaticText->SetFocus();
- Message.Result = 1;
- }
- else if (Message.Msg == WM_CHAR)
- {
- if (reinterpret_cast<TWMChar &>(Message).CharCode == L' ')
- {
- Clicked = true;
- Message.Result = 1;
- }
- else
- {
- ControlWndProc(StaticText)(Message);
- }
- }
- else if (Message.Msg == CM_DIALOGCHAR)
- {
- if (StaticText->CanFocus() && StaticText->ShowAccelChar &&
- IsAccel(reinterpret_cast<TCMDialogChar &>(Message).CharCode, StaticText->Caption))
- {
- StaticText->SetFocus();
- // in case the action takes long, make sure focus is shown immediatelly
- UpdateWindow(StaticText->Handle);
- Clicked = true;
- Message.Result = 1;
- }
- else
- {
- ControlWndProc(StaticText)(Message);
- }
- }
- else
- {
- ControlWndProc(StaticText)(Message);
- }
- if (Message.Msg == WM_PAINT)
- {
- TRect R;
- TControlCanvas * Canvas;
- FocusableLabelCanvas(StaticText, &Canvas, R);
- try
- {
- if (StaticText->Focused())
- {
- Canvas->DrawFocusRect(R);
- }
- else if (!StaticText->Font->Style.Contains(fsUnderline))
- {
- Canvas->Pen->Style = psDot;
- Canvas->Brush->Style = bsClear;
- if (!StaticText->Enabled)
- {
- Canvas->Pen->Color = clBtnHighlight;
- Canvas->MoveTo(R.Left + 1 + 1, R.Bottom);
- Canvas->LineTo(R.Right + 1, R.Bottom);
- Canvas->Pen->Color = clGrayText;
- }
- Canvas->MoveTo(R.Left, R.Bottom - 1);
- Canvas->LineTo(R.Right, R.Bottom - 1);
- }
- }
- __finally
- {
- delete Canvas;
- }
- }
- else if ((Message.Msg == WM_SETFOCUS) || (Message.Msg == WM_KILLFOCUS) ||
- (Message.Msg == CM_ENABLEDCHANGED))
- {
- StaticText->Invalidate();
- }
- }
- //---------------------------------------------------------------------------
- static THintWindow * PersistentHintWindow = NULL;
- static TControl * PersistentHintControl = NULL;
- //---------------------------------------------------------------------------
- void __fastcall CancelPersistentHint()
- {
- if (PersistentHintWindow != NULL)
- {
- PersistentHintControl = NULL;
- SAFE_DESTROY(PersistentHintWindow);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall ShowPersistentHint(TControl * Control, TPoint HintPos)
- {
- CancelPersistentHint();
- THintInfo HintInfo;
- HintInfo.HintControl = Control;
- HintInfo.HintPos = HintPos;
- HintInfo.HintMaxWidth = GetParentForm(Control)->Monitor->Width;
- HintInfo.HintColor = Application->HintColor;
- HintInfo.HintStr = GetShortHint(Control->Hint);
- HintInfo.HintData = NULL;
- bool CanShow = true;
- if (Application->OnShowHint != NULL)
- {
- Application->OnShowHint(HintInfo.HintStr, CanShow, HintInfo);
- }
- if (CanShow)
- {
- PersistentHintControl = Control;
- PersistentHintWindow = new THintWindow(Application);
- PersistentHintWindow->BiDiMode = Control->BiDiMode;
- PersistentHintWindow->Color = HintInfo.HintColor;
- TRect HintWinRect;
- if (HintInfo.HintMaxWidth < Control->Width)
- {
- HintInfo.HintMaxWidth = Control->Width;
- }
- HintWinRect = PersistentHintWindow->CalcHintRect(
- HintInfo.HintMaxWidth, HintInfo.HintStr, HintInfo.HintData);
- OffsetRect(HintWinRect, HintInfo.HintPos.x, HintInfo.HintPos.y);
- // TODO: right align window placement for UseRightToLeftAlignment, see Forms.pas
- PersistentHintWindow->ActivateHintData(HintWinRect, HintInfo.HintStr, HintInfo.HintData);
- }
- }
- //---------------------------------------------------------------------------
- static void __fastcall HintLabelWindowProc(void * Data, TMessage & Message)
- {
- bool Clicked = false;
- bool Cancel = false;
- TStaticText * StaticText = static_cast<TStaticText *>(Data);
- if (Message.Msg == CM_HINTSHOW)
- {
- TCMHintShow & HintShow = reinterpret_cast<TCMHintShow &>(Message);
- if (PersistentHintControl == StaticText)
- {
- // do not allow standard hint when persistent is already shown
- HintShow.Result = 1;
- }
- else
- {
- HintShow.HintInfo->HideTimeout = 100000; // never
- }
- }
- else if (Message.Msg == CN_KEYDOWN)
- {
- if ((reinterpret_cast<TWMKey &>(Message).CharCode == VK_ESCAPE) &&
- (PersistentHintControl == StaticText))
- {
- CancelPersistentHint();
- StaticText->Invalidate();
- Message.Result = 1;
- }
- else
- {
- FocusableLabelWindowProc(Data, Message, Clicked);
- }
- }
- else
- {
- FocusableLabelWindowProc(Data, Message, Clicked);
- }
- if (Message.Msg == CM_CANCELMODE)
- {
- TCMCancelMode & CancelMessage = (TCMCancelMode&)Message;
- if ((CancelMessage.Sender != StaticText) &&
- (CancelMessage.Sender != PersistentHintWindow))
- {
- Cancel = true;
- }
- }
- if ((Message.Msg == WM_DESTROY) || (Message.Msg == WM_KILLFOCUS))
- {
- Cancel = true;
- }
- if (Cancel && (PersistentHintControl == StaticText))
- {
- CancelPersistentHint();
- }
- if (Clicked && (PersistentHintControl != StaticText))
- {
- TRect R;
- TPoint HintPos;
- FocusableLabelCanvas(StaticText, NULL, R);
- HintPos.y = R.Bottom - R.Top;
- HintPos.x = R.Left;
- ShowPersistentHint(StaticText, StaticText->ClientToScreen(HintPos));
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall HintLabel(TStaticText * StaticText, UnicodeString Hint)
- {
- // Currently all are right-justified, when other alignemtn is used,
- // test respective branches in FocusableLabelCanvas.
- assert(StaticText->Alignment == taRightJustify);
- // With right-justify, it has to be off. We may not notice on riginal
- // English version, results will differ with translations only
- assert(!StaticText->AutoSize);
- StaticText->ParentFont = true;
- if (!Hint.IsEmpty())
- {
- StaticText->Hint = Hint;
- }
- StaticText->ShowHint = true;
- StaticText->Cursor = crHandPoint;
- TWndMethod WindowProc;
- ((TMethod*)&WindowProc)->Data = StaticText;
- ((TMethod*)&WindowProc)->Code = HintLabelWindowProc;
- StaticText->WindowProc = WindowProc;
- }
- //---------------------------------------------------------------------------
- void __fastcall HintLabelRestore(TStaticText * StaticText)
- {
- StaticText->WindowProc = ControlWndProc(StaticText);
- StaticText->ShowHint = false;
- StaticText->Cursor = crDefault;
- }
- //---------------------------------------------------------------------------
- static void __fastcall ComboBoxFixWindowProc(void * Data, TMessage & Message)
- {
- // it is TCustomComboxBox, but the properties are published only by TComboBox
- TComboBox * ComboBox = static_cast<TComboBox *>(Data);
- if (Message.Msg == WM_SIZE)
- {
- UnicodeString Text = ComboBox->Text;
- try
- {
- ControlWndProc(ComboBox)(Message);
- }
- __finally
- {
- // workaround for bug in combo box, that causes it to change text to any
- // item from drop down list which starts with current text,
- // after control is resized (unless the text is in drop down list as well)
- ComboBox->Text = Text;
- // hide selection, which is wrongly shown when form is resized, even when the box has not focus
- if (!ComboBox->Focused())
- {
- ComboBox->SelLength = 0;
- }
- }
- }
- else
- {
- ControlWndProc(ComboBox)(Message);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall FixComboBoxResizeBug(TCustomComboBox * ComboBox)
- {
- TWndMethod WindowProc;
- ((TMethod*)&WindowProc)->Data = ComboBox;
- ((TMethod*)&WindowProc)->Code = ComboBoxFixWindowProc;
- ComboBox->WindowProc = WindowProc;
- }
- //---------------------------------------------------------------------------
- static void __fastcall LinkLabelClick(TStaticText * StaticText)
- {
- if (StaticText->OnClick != NULL)
- {
- StaticText->OnClick(StaticText);
- }
- else
- {
- UnicodeString Url = StaticText->Caption;
- if (!SameText(Url.SubString(1, 4), L"http") && (Url.Pos(L"@") > 0))
- {
- Url = L"mailto:" + Url;
- }
- OpenBrowser(Url);
- }
- }
- //---------------------------------------------------------------------------
- static void __fastcall LinkLabelWindowProc(void * Data, TMessage & Message)
- {
- bool Clicked = false;
- TStaticText * StaticText = static_cast<TStaticText *>(Data);
- if (Message.Msg == WM_CONTEXTMENU)
- {
- TWMContextMenu & ContextMenu = reinterpret_cast<TWMContextMenu &>(Message);
- if ((ContextMenu.Pos.x < 0) && (ContextMenu.Pos.y < 0))
- {
- TRect R;
- FocusableLabelCanvas(StaticText, NULL, R);
- TPoint P = StaticText->ClientToScreen(TPoint(R.Left, R.Bottom));
- ContextMenu.Pos.x = static_cast<short>(P.x);
- ContextMenu.Pos.y = static_cast<short>(P.y);
- }
- }
- else if (Message.Msg == WM_KEYDOWN)
- {
- TWMKey & Key = reinterpret_cast<TWMKey &>(Message);
- if ((GetKeyState(VK_CONTROL) < 0) && (Key.CharCode == L'C'))
- {
- TInstantOperationVisualizer Visualizer;
- CopyToClipboard(StaticText->Caption);
- Message.Result = 1;
- }
- else
- {
- FocusableLabelWindowProc(Data, Message, Clicked);
- }
- }
- FocusableLabelWindowProc(Data, Message, Clicked);
- if (Message.Msg == WM_DESTROY)
- {
- delete StaticText->PopupMenu;
- assert(StaticText->PopupMenu == NULL);
- }
- if (Clicked)
- {
- LinkLabelClick(StaticText);
- }
- }
- //---------------------------------------------------------------------------
- static void __fastcall LinkLabelContextMenuClick(void * Data, TObject * Sender)
- {
- TStaticText * StaticText = static_cast<TStaticText *>(Data);
- TMenuItem * MenuItem = dynamic_cast<TMenuItem *>(Sender);
- assert(MenuItem != NULL);
- if (MenuItem->Tag == 0)
- {
- LinkLabelClick(StaticText);
- }
- else
- {
- TInstantOperationVisualizer Visualizer;
- CopyToClipboard(StaticText->Caption);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall LinkLabel(TStaticText * StaticText, UnicodeString Url,
- TNotifyEvent OnEnter)
- {
- StaticText->Transparent = false;
- StaticText->ParentFont = true;
- StaticText->Font->Style = StaticText->Font->Style << fsUnderline;
- StaticText->Font->Color = clBlue;
- StaticText->Cursor = crHandPoint;
- reinterpret_cast<TButton*>(StaticText)->OnEnter = OnEnter;
- if (!Url.IsEmpty())
- {
- StaticText->Caption = Url;
- }
- if (StaticText->OnClick == NULL)
- {
- assert(StaticText->PopupMenu == NULL);
- StaticText->PopupMenu = new TPopupMenu(StaticText);
- try
- {
- TNotifyEvent ContextMenuOnClick;
- ((TMethod*)&ContextMenuOnClick)->Data = StaticText;
- ((TMethod*)&ContextMenuOnClick)->Code = LinkLabelContextMenuClick;
- TMenuItem * Item;
- Item = new TMenuItem(StaticText->PopupMenu);
- Item->Caption = LoadStr(URL_LINK_OPEN);
- Item->Tag = 0;
- Item->ShortCut = ShortCut(L' ', TShiftState());
- Item->OnClick = ContextMenuOnClick;
- StaticText->PopupMenu->Items->Add(Item);
- Item = new TMenuItem(StaticText->PopupMenu);
- Item->Caption = LoadStr(URL_LINK_COPY);
- Item->Tag = 1;
- Item->ShortCut = ShortCut(L'C', TShiftState() << ssCtrl);
- Item->OnClick = ContextMenuOnClick;
- StaticText->PopupMenu->Items->Add(Item);
- }
- catch(...)
- {
- delete StaticText->PopupMenu;
- assert(StaticText->PopupMenu == NULL);
- throw;
- }
- }
- TWndMethod WindowProc;
- ((TMethod*)&WindowProc)->Data = StaticText;
- ((TMethod*)&WindowProc)->Code = LinkLabelWindowProc;
- StaticText->WindowProc = WindowProc;
- }
- //---------------------------------------------------------------------------
- static void __fastcall HotTrackLabelMouseEnter(void * /*Data*/, TObject * Sender)
- {
- reinterpret_cast<TLabel *>(Sender)->Font->Color = clBlue;
- }
- //---------------------------------------------------------------------------
- static void __fastcall HotTrackLabelMouseLeave(void * /*Data*/, TObject * Sender)
- {
- reinterpret_cast<TLabel *>(Sender)->ParentFont = true;
- }
- //---------------------------------------------------------------------------
- void __fastcall HotTrackLabel(TLabel * Label)
- {
- assert(Label->OnMouseEnter == NULL);
- assert(Label->OnMouseLeave == NULL);
- Label->OnMouseEnter = MakeMethod<TNotifyEvent>(NULL, HotTrackLabelMouseEnter);
- Label->OnMouseLeave = MakeMethod<TNotifyEvent>(NULL, HotTrackLabelMouseLeave);
- }
- //---------------------------------------------------------------------------
- Forms::TMonitor * __fastcall FormMonitor(TCustomForm * Form)
- {
- Forms::TMonitor * Result;
- if ((Application->MainForm != NULL) && (Application->MainForm != Form))
- {
- Result = Application->MainForm->Monitor;
- }
- else if (LastMonitor != NULL)
- {
- Result = LastMonitor;
- }
- else
- {
- int i = 0;
- while ((i < Screen->MonitorCount) && !Screen->Monitors[i]->Primary)
- {
- i++;
- }
- assert(Screen->Monitors[i]->Primary);
- Result = Screen->Monitors[i];
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- int __fastcall GetLastMonitor()
- {
- if (LastMonitor != NULL)
- {
- return LastMonitor->MonitorNum;
- }
- else
- {
- return -1;
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall SetLastMonitor(int MonitorNum)
- {
- if ((MonitorNum >= 0) && (MonitorNum < Screen->MonitorCount))
- {
- LastMonitor = Screen->Monitors[MonitorNum];
- }
- else
- {
- LastMonitor = NULL;
- }
- }
- //---------------------------------------------------------------------------
- TForm * __fastcall _SafeFormCreate(TMetaClass * FormClass, TComponent * Owner)
- {
- TForm * Form;
- if (Owner == NULL)
- {
- Owner = GetFormOwner();
- }
- // If there is no main form yet, make this one main.
- // This:
- // - Makes other forms (dialogs invoked from this one),
- // be placed on the same monitor (otherwise all new forms get placed
- // on primary monitor)
- // - Triggers MainForm-specific code in DoFormWindowProc.
- // - Shows button on taskbar
- if (Application->MainForm == NULL)
- {
- Application->CreateForm(FormClass, &Form);
- assert(Application->MainForm == Form);
- }
- else
- {
- Form = dynamic_cast<TForm *>(Construct(FormClass, Owner));
- assert(Form != NULL);
- }
- return Form;
- }
- //---------------------------------------------------------------------------
- TImageList * __fastcall SharedSystemImageList(bool Large)
- {
- TSHFileInfo FileInfo;
- TImageList * Result = new TImageList(Application);
- int ImageListHandle = SHGetFileInfo(L"", 0, &FileInfo, sizeof(FileInfo),
- SHGFI_SYSICONINDEX | (Large ? SHGFI_LARGEICON : SHGFI_SMALLICON));
- if (ImageListHandle != 0)
- {
- Result->ShareImages = true;
- Result->Handle = ImageListHandle;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- bool __fastcall SupportsSplitButton()
- {
- return (Win32MajorVersion >= 6);
- }
- //---------------------------------------------------------------------------
- static TButton * __fastcall FindDefaultButton(TWinControl * Control)
- {
- TButton * Result = NULL;
- int Index = 0;
- while ((Result == NULL) && (Index < Control->ControlCount))
- {
- TControl * ChildControl = Control->Controls[Index];
- TButton * Button = dynamic_cast<TButton *>(ChildControl);
- if ((Button != NULL) && Button->Default)
- {
- Result = Button;
- }
- else
- {
- TWinControl * WinControl = dynamic_cast<TWinControl *>(ChildControl);
- if (WinControl != NULL)
- {
- Result = FindDefaultButton(WinControl);
- }
- }
- Index++;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- TModalResult __fastcall DefaultResult(TCustomForm * Form)
- {
- // The point of this is to avoid hardcoding mrOk when checking dialog results.
- // Previously we used != mrCancel instead, as mrCancel is more reliable,
- // being automatically used for Esc/X buttons (and hence kind of forced to be used
- // for Cancel buttons). But that failed to be reliable in the end, for
- // ModalResult being mrNone, when Windows session is being logged off.
- // We interpreted mrNone as OK, causing lots of troubles.
- TModalResult Result = mrNone;
- TButton * Button = FindDefaultButton(Form);
- if (ALWAYS_TRUE(Button != NULL))
- {
- Result = Button->ModalResult;
- }
- if (ALWAYS_FALSE(Result == mrNone))
- {
- Result = mrOk;
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- void __fastcall SetFormIcon(TForm * Form, int Size, const UnicodeString & IconName)
- {
- HICON Icon = LoadIcon(HInstance, IconName.c_str());
- if (ALWAYS_TRUE(Icon != NULL))
- {
- LPARAM LParam = reinterpret_cast<LPARAM>(Icon);
- SendMessage(Form->Handle, WM_SETICON, Size, LParam);
- DestroyIcon(Icon);
- }
- }
- //---------------------------------------------------------------------------
- void __fastcall SetFormIcons(TForm * Form, const UnicodeString & BigIconName,
- const UnicodeString & SmallIconName)
- {
- SetFormIcon(Form, ICON_SMALL, SmallIconName);
- SetFormIcon(Form, ICON_BIG, BigIconName);
- }
- //---------------------------------------------------------------------------
- void __fastcall UseDesktopFont(TControl * Control)
- {
- TCustomStatusBar * StatusBar = dynamic_cast<TCustomStatusBar *>(Control);
- if (StatusBar != NULL)
- {
- // otherwise setting DesktopFont below has no effect
- StatusBar->UseSystemFont = false;
- }
- class TPublicControl : public TControl
- {
- public:
- __property DesktopFont;
- };
- reinterpret_cast<TPublicControl *>(Control)->DesktopFont = true;
- }
- //---------------------------------------------------------------------------
- void __fastcall LoadResourceImage(TImage * Image, const UnicodeString & ImageName)
- {
- std::unique_ptr<TPngImage> Png(new TPngImage());
- Png->LoadFromResourceName(0, ImageName);
- Image->Picture->Assign(Png.get());
- }
|