From e23b866f4bd809775a1e21fa8c39ac8ed29cd387 Mon Sep 17 00:00:00 2001 From: avan Date: Sun, 3 Mar 2024 14:44:11 +0800 Subject: [PATCH] Add support for Hotkeys feature. Currently, the hotkeys are hardcoded in the program... --- PS4CheaterNeo/HexEditor.cs | 40 +++ PS4CheaterNeo/Main.cs | 40 +++ PS4CheaterNeo/Properties/AssemblyInfo.cs | 4 +- PS4CheaterNeo/Query.cs | 59 +++- .../common/CollapsibleSplitContainer.cs | 252 +++++++++--------- PS4CheaterNeo/lib/GroupGridView.dll | Bin 28672 -> 28672 bytes README.md | 81 +++++- 7 files changed, 335 insertions(+), 141 deletions(-) diff --git a/PS4CheaterNeo/HexEditor.cs b/PS4CheaterNeo/HexEditor.cs index eafbac9..169c2d4 100644 --- a/PS4CheaterNeo/HexEditor.cs +++ b/PS4CheaterNeo/HexEditor.cs @@ -104,6 +104,46 @@ public HexEditor(Main mainForm, SectionTool sectionTool, Section section, int ba InitPageData(section, baseAddr); } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + switch (keyData) + { + case Keys.Control | Keys.P: + PreviousBtn.PerformClick(); + break; + case Keys.Control | Keys.N: + NextBtn.PerformClick(); + break; + case Keys.Control | Keys.R: + RefreshBtn.PerformClick(); + break; + case Keys.Control | Keys.S: + CommitBtn.PerformClick(); + break; + case Keys.Control | Keys.A: + AddToCheatGridBtn.PerformClick(); + break; + case Keys.F3: + FindBtn.PerformClick(); + break; + case Keys.Control | Keys.Left: + SplitContainer1.SplitterPanelCollapseExpand(true); + break; + case Keys.Control | Keys.Right: + SplitContainer1.SplitterPanelCollapseExpand(false); + break; + case Keys.Control | Keys.Up: + SplitContainer2.SplitterPanelCollapseExpand(true); + break; + case Keys.Control | Keys.Down: + SplitContainer2.SplitterPanelCollapseExpand(false); + break; + default: + return base.ProcessCmdKey(ref msg, keyData); + } + return true; + } + /// /// Initialize the contents of the PageBox menu based on the specified Section and /// select the corresponding PageBox menu based on the relative address (baseAddr). diff --git a/PS4CheaterNeo/Main.cs b/PS4CheaterNeo/Main.cs index 760ea19..4cb0bc0 100644 --- a/PS4CheaterNeo/Main.cs +++ b/PS4CheaterNeo/Main.cs @@ -74,6 +74,46 @@ public Main() CheatGridView.RowCount = 0; } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + switch (keyData) + { + case Keys.Control | Keys.O: + ToolStripOpen.PerformClick(); + break; + case Keys.Control | Keys.S: + ToolStripSave.PerformClick(); + break; + case Keys.Control | Keys.Q: + ToolStripNewQuery.PerformClick(); + break; + case Keys.Control | Keys.A: + ToolStripAdd.PerformClick(); + break; + case Keys.Control | Keys.H: + ToolStripHexView.PerformClick(); + break; + case Keys.Control | Keys.R: + ToolStripRefreshCheat.PerformClick(); + break; + case Keys.Alt | Keys.E: + CheatGridView.CollapseExpandAll(); + break; + case Keys.Alt | Keys.L: + ToolStripLockEnable.PerformClick(); + break; + case Keys.Alt | Keys.R: + ToolStripAutoRefresh.PerformClick(); + break; + case Keys.Alt | Keys.S: + ToolStripSettings.PerformClick(); + break; + default: + return base.ProcessCmdKey(ref msg, keyData); + } + return true; + } + public void ParseLanguageJson() { string codes = Properties.Settings.Default.UILanguage.Value.ToString(); diff --git a/PS4CheaterNeo/Properties/AssemblyInfo.cs b/PS4CheaterNeo/Properties/AssemblyInfo.cs index 3c9e4a9..c90b3f6 100644 --- a/PS4CheaterNeo/Properties/AssemblyInfo.cs +++ b/PS4CheaterNeo/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.2.8")] -[assembly: AssemblyFileVersion("1.0.2.8")] +[assembly: AssemblyVersion("1.0.2.9")] +[assembly: AssemblyFileVersion("1.0.2.9")] diff --git a/PS4CheaterNeo/Query.cs b/PS4CheaterNeo/Query.cs index 7c04c2b..550abeb 100644 --- a/PS4CheaterNeo/Query.cs +++ b/PS4CheaterNeo/Query.cs @@ -76,6 +76,52 @@ public Query(Main mainForm, ComparerTool comparerTool = null, int bitsDictDictsI this.bitsDictDicts = new List>(bitsDictDicts); } + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + switch (keyData) + { + case Keys.Control | Keys.G: + GetProcessesBtn.PerformClick(); + break; + case Keys.Control | Keys.P: + PauseResume(); + break; + case Keys.Alt | Keys.S: + ScanBtn.PerformClick(); + break; + case Keys.Alt | Keys.U: + UndoBtn.PerformClick(); + break; + case Keys.Alt | Keys.R: + RedoBtn.PerformClick(); + break; + case Keys.Control | Keys.R: + RefreshBtn.PerformClick(); + break; + case Keys.Control | Keys.N: + NewBtn.PerformClick(); + break; + case Keys.Alt | Keys.C: + CloneScanBtn.PerformClick(); + break; + case Keys.Control | Keys.Left: + SplitContainer1.SplitterPanelCollapseExpand(true); + break; + case Keys.Control | Keys.Right: + SplitContainer1.SplitterPanelCollapseExpand(false); + break; + case Keys.Control | Keys.Up: + SplitContainer2.SplitterPanelCollapseExpand(true); + break; + case Keys.Control | Keys.Down: + SplitContainer2.SplitterPanelCollapseExpand(false); + break; + default: + return base.ProcessCmdKey(ref msg, keyData); + } + return true; + } + public void ApplyUI(LanguageJson langJson) { try @@ -1578,16 +1624,13 @@ private void CompareTypeBox_SelectedIndexChanged(object sender, EventArgs e) } } - private void ResumeBtn_Click(object sender, EventArgs e) - { - processStatus = ProcessStatus.Resume; - ComboItem process = (ComboItem)ProcessesBox.SelectedItem; - PS4Tool.AttachDebugger((int)process.Value, (string)process.Text, processStatus); - } + private void ResumeBtn_Click(object sender, EventArgs e) => PauseResume(ProcessStatus.Resume); + + private void PauseBtn_Click(object sender, EventArgs e) => PauseResume(ProcessStatus.Pause); - private void PauseBtn_Click(object sender, EventArgs e) + private void PauseResume(ProcessStatus? newStatus = null) { - processStatus = ProcessStatus.Pause; + processStatus = newStatus != null ? (ProcessStatus)newStatus : (processStatus == ProcessStatus.Pause ? ProcessStatus.Resume : ProcessStatus.Pause); ComboItem process = (ComboItem)ProcessesBox.SelectedItem; PS4Tool.AttachDebugger((int)process.Value, (string)process.Text, processStatus); } diff --git a/PS4CheaterNeo/common/CollapsibleSplitContainer.cs b/PS4CheaterNeo/common/CollapsibleSplitContainer.cs index af88ccb..fadcb64 100644 --- a/PS4CheaterNeo/common/CollapsibleSplitContainer.cs +++ b/PS4CheaterNeo/common/CollapsibleSplitContainer.cs @@ -32,8 +32,8 @@ public class CollapsibleSplitContainer : SplitContainer, ISupportInitialize private ButtonPosition splitterButtonPosition; private CollapseDistance splitterCollapseDistance; - private Button splitterButton1; - private Button splitterButton2; + private Button SplitterButton1; + private Button SplitterButton2; private readonly string TableFillLeft = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAuElEQVR4XqXTsQ3DIBAF0Is7iyYV9F4gK1hikWQEOjwBdIyQbJAsgJQVsgA9VGksSgdXJxFFoMs1V6D/kPjisG0btCbnfCxrHsfxUZ8NneHnuq73Ap27gDrsnDtpraEg1xoZesLee0gpQYwRdQTaYcYYGGNgmqZLeYdbBZDCCJDDCNDDCNAHgXLLu6xZKfWSUu6VwbIsEELA6n4BRAQBIoIAGUGgjXDOQQjR30KNWGv3ar8q/fs7fwCWA6ahjYFLQgAAAABJRU5ErkJggg=="; #endregion @@ -46,22 +46,22 @@ public CollapsibleSplitContainer() MethodInfo objMethodInfo = typeof(Control).GetMethod("SetStyle", BindingFlags.NonPublic | BindingFlags.Instance); objMethodInfo.Invoke(Panel1, objArgs); objMethodInfo.Invoke(Panel2, objArgs); - splitterButton1 = new Button(); - splitterButton2 = new Button(); - splitterButton1.Size = new Size(16, 16); - splitterButton2.Size = new Size(16, 16); - splitterButton1.Margin = new Padding(0); - splitterButton2.Margin = new Padding(0); - splitterButton1.BackgroundImageLayout = ImageLayout.Zoom; - splitterButton2.BackgroundImageLayout = ImageLayout.Zoom; - splitterButton1.BackColor = Color.Transparent; - splitterButton2.BackColor = Color.Transparent; - splitterButton1.FlatStyle = FlatStyle.Flat; - splitterButton2.FlatStyle = FlatStyle.Flat; - splitterButton1.FlatAppearance.BorderSize = 0; - splitterButton2.FlatAppearance.BorderSize = 0; - splitterButton1.Click += SplitterButton1_Click; - splitterButton2.Click += SplitterButton2_Click; + SplitterButton1 = new Button(); + SplitterButton2 = new Button(); + SplitterButton1.Size = new Size(16, 16); + SplitterButton2.Size = new Size(16, 16); + SplitterButton1.Margin = new Padding(0); + SplitterButton2.Margin = new Padding(0); + SplitterButton1.BackgroundImageLayout = ImageLayout.Zoom; + SplitterButton2.BackgroundImageLayout = ImageLayout.Zoom; + SplitterButton1.BackColor = Color.Transparent; + SplitterButton2.BackColor = Color.Transparent; + SplitterButton1.FlatStyle = FlatStyle.Flat; + SplitterButton2.FlatStyle = FlatStyle.Flat; + SplitterButton1.FlatAppearance.BorderSize = 0; + SplitterButton2.FlatAppearance.BorderSize = 0; + SplitterButton1.Click += SplitterButton1_Click; + SplitterButton2.Click += SplitterButton2_Click; SplitterButtonSize = 16; SplitterButtonStyle = ButtonStyle.Image; @@ -98,7 +98,7 @@ public Bitmap SplitterButtonBitmap } } - [Category("Collapsible"), Description("Where the collapse buttons are located on the splitter")] + [Category("Collapsible"), Description("Determines whether to place collapse buttons on both sides of the splitter or on one side of Panel1 and Panel2")] [DefaultValue(ButtonLocation.Panel)] public ButtonLocation SplitterButtonLocation { @@ -108,31 +108,31 @@ public ButtonLocation SplitterButtonLocation splitterButtonLocation = value; if (splitterCollapseDistance == CollapseDistance.Collapsed || splitterButtonLocation == ButtonLocation.Panel) { - if (!Panel1.Controls.Contains(splitterButton1)) Panel1.Controls.Add(splitterButton1); - if (!Panel2.Controls.Contains(splitterButton2)) Panel2.Controls.Add(splitterButton2); - if (Panel2.Controls.Contains(splitterButton1)) Panel2.Controls.Remove(splitterButton1); - if (Panel1.Controls.Contains(splitterButton2)) Panel1.Controls.Remove(splitterButton2); + if (!Panel1.Controls.Contains(SplitterButton1)) Panel1.Controls.Add(SplitterButton1); + if (!Panel2.Controls.Contains(SplitterButton2)) Panel2.Controls.Add(SplitterButton2); + if (Panel2.Controls.Contains(SplitterButton1)) Panel2.Controls.Remove(SplitterButton1); + if (Panel1.Controls.Contains(SplitterButton2)) Panel1.Controls.Remove(SplitterButton2); } else if (splitterButtonLocation == ButtonLocation.Panel1) { - if (!Panel1.Controls.Contains(splitterButton1)) Panel1.Controls.Add(splitterButton1); - if (!Panel1.Controls.Contains(splitterButton2)) Panel1.Controls.Add(splitterButton2); - if (Panel2.Controls.Contains(splitterButton1)) Panel2.Controls.Remove(splitterButton1); - if (Panel2.Controls.Contains(splitterButton2)) Panel2.Controls.Remove(splitterButton2); + if (!Panel1.Controls.Contains(SplitterButton1)) Panel1.Controls.Add(SplitterButton1); + if (!Panel1.Controls.Contains(SplitterButton2)) Panel1.Controls.Add(SplitterButton2); + if (Panel2.Controls.Contains(SplitterButton1)) Panel2.Controls.Remove(SplitterButton1); + if (Panel2.Controls.Contains(SplitterButton2)) Panel2.Controls.Remove(SplitterButton2); } else if (splitterButtonLocation == ButtonLocation.Panel2) { - if (!Panel2.Controls.Contains(splitterButton1)) Panel2.Controls.Add(splitterButton1); - if (!Panel2.Controls.Contains(splitterButton2)) Panel2.Controls.Add(splitterButton2); - if (Panel1.Controls.Contains(splitterButton1)) Panel1.Controls.Remove(splitterButton1); - if (Panel1.Controls.Contains(splitterButton2)) Panel1.Controls.Remove(splitterButton2); + if (!Panel2.Controls.Contains(SplitterButton1)) Panel2.Controls.Add(SplitterButton1); + if (!Panel2.Controls.Contains(SplitterButton2)) Panel2.Controls.Add(SplitterButton2); + if (Panel1.Controls.Contains(SplitterButton1)) Panel1.Controls.Remove(SplitterButton1); + if (Panel1.Controls.Contains(SplitterButton2)) Panel1.Controls.Remove(SplitterButton2); } else { - Panel1.Controls.Remove(splitterButton1); - Panel1.Controls.Remove(splitterButton2); - Panel2.Controls.Remove(splitterButton1); - Panel2.Controls.Remove(splitterButton2); + Panel1.Controls.Remove(SplitterButton1); + Panel1.Controls.Remove(SplitterButton2); + Panel2.Controls.Remove(SplitterButton1); + Panel2.Controls.Remove(SplitterButton2); } Refresh(); UpdateSplitterButtonsPosition(); @@ -153,7 +153,7 @@ public ButtonPosition SplitterButtonPosition } } - [Category("Collapsible"), Description("The technique used to generate the splitter buttons")] + [Category("Collapsible"), Description("Determines the style of splitter buttons: Image - displayed on both sides of the panel; SingleImage - displayed on one side; None - not displayed.")] [DefaultValue(ButtonStyle.Image)] public ButtonStyle SplitterButtonStyle { @@ -164,13 +164,13 @@ public ButtonStyle SplitterButtonStyle splitterButtonStyle = value; if (splitterButtonStyle == ButtonStyle.None) { - splitterButton1.Hide(); - splitterButton2.Hide(); + SplitterButton1.Hide(); + SplitterButton2.Hide(); } else { - splitterButton1.Show(); - splitterButton2.Show(); + SplitterButton1.Show(); + SplitterButton2.Show(); } Refresh(); } @@ -185,16 +185,16 @@ public int SplitterButtonSize { if (splitterButtonSize == value) return; splitterButtonSize = value; - var size = splitterButton1.Size; + var size = SplitterButton1.Size; size.Width = SplitterButtonSize; size.Height = SplitterButtonSize; - splitterButton1.Size = size; - splitterButton2.Size = size; + SplitterButton1.Size = size; + SplitterButton2.Size = size; Refresh(); } } - [Category("Collapsible"), Description("How completely the affected panel collapses")] + [Category("Collapsible"), Description("Determines the style of the splitter after collapsing: MinSize - the panel collapses to the specified MinSize; Collapsed - One-sided panel completely collapsed")] [DefaultValue(CollapseDistance.MinSize)] public CollapseDistance SplitterCollapseDistance { @@ -239,7 +239,7 @@ public CollapseDistance SplitterCollapseDistance } } - [Category("Collapsible"), Description("Determines whether to collapse Panel2 when SplitterButtonStyle is SingleImage, otherwise Panel1 collapse")] + [Category("Collapsible"), Description("Determines whether to collapse Panel2; if not, Panel1 will collapse. This setting only takes effect when SplitterButtonStyle is SingleImage and the location of the splitter button is on either Panel1 or Panel2.")] [DefaultValue(true)] public bool SingleImageCollapsePanel2 { get; set; } = true; @@ -282,78 +282,67 @@ public CollapseDistance SplitterCollapseDistance #endregion #region General Event Handlers - private void SplitterButton1_Click(object sender, EventArgs e) + private void SplitterButton1_Click(object sender, EventArgs e) => SplitterPanelCollapseExpand(true); + + private void SplitterButton2_Click(object sender, EventArgs e) => SplitterPanelCollapseExpand(false); + + private bool clickSplitterButtonStaus = false; + + /// + /// Trigger the collapse or expand of the splitter panel. + /// When status parameter is true, Panel1 collapses; when status is false, Panel2 collapses. + /// If the status parameter is not provided, it will automatically determine whether to collapse or expand. + /// + public void SplitterPanelCollapseExpand(bool? status = null) { if (splitterButtonStyle == ButtonStyle.None) return; + if (status == null) + { + status = clickSplitterButtonStaus; + clickSplitterButtonStaus = !clickSplitterButtonStaus; + } + object sender = (bool)status ? SplitterButton1 : SplitterButton2; + if (splitterCollapseDistance == CollapseDistance.Collapsed) { // Hide the panel associated with the clicked button if (Panel1Collapsed && !Panel2Collapsed) Panel2Collapsed = !Panel2Collapsed; else if (!Panel1Collapsed && Panel2Collapsed) Panel1Collapsed = !Panel1Collapsed; - else Panel1Collapsed = true; + else if (sender == SplitterButton1) Panel1Collapsed = true; + else if (sender == SplitterButton2) Panel2Collapsed = true; } else if (splitterCollapseDistance == CollapseDistance.MinSize) { - // If the panel for the clicked button is already minimized, do nothing - // Otherwise, have the panel shrink to or return from the minimum size - if (Panel1Minimized) - { - if (splitterButtonStyle == ButtonStyle.SingleImage) splitterButton2.BringToFront(); - return; - } - else if (Panel2Minimized) // Panel 2 - { - SplitterDistance = splitterDistanceOriginal; - Panel2Minimized = false; - } - else // Panel 1 + if (!Panel1Minimized && !Panel2Minimized) { splitterDistanceOriginal = SplitterDistance; - SplitterDistance = Panel1MinSize; - Panel1Minimized = true; + if (sender == SplitterButton1) + { // Panel 1 + (SplitterDistance, Panel1Minimized) = (Panel1MinSize, true); + } + else if (sender == SplitterButton2) + { // Panel 2 + // When the splitter is vertical, set the location of the splitter to + // the splitcontainer control width minus the minimum size of panel 2. + // For horizontal, set it to height minus panel 2 minimum size + (SplitterDistance, Panel2Minimized) = (Orientation == Orientation.Vertical ? Width - Panel2MinSize : Height - Panel2MinSize, true); + } } - } - Refresh(); - } - - private void SplitterButton2_Click(object sender, EventArgs e) - { - if (splitterButtonStyle == ButtonStyle.None) return; - - if (splitterCollapseDistance == CollapseDistance.Collapsed) - { - // Hide the panel associated with the clicked button - if (!Panel1Collapsed && Panel2Collapsed) Panel1Collapsed = !Panel1Collapsed; - else if (Panel1Collapsed && !Panel2Collapsed) Panel2Collapsed = !Panel2Collapsed; - else Panel2Collapsed = true; - } - else if (splitterCollapseDistance == CollapseDistance.MinSize) - { // If the panel for the clicked button is already minimized, do nothing // Otherwise, have the panel shrink to or return from the minimum size - if (Panel2Minimized) + else if (Panel1Minimized && sender == SplitterButton2) + (SplitterDistance, Panel1Minimized) = (splitterDistanceOriginal, false); + else if (Panel2Minimized && sender == SplitterButton1) + (SplitterDistance, Panel2Minimized) = (splitterDistanceOriginal, false); + else { - if (splitterButtonStyle == ButtonStyle.SingleImage) splitterButton1.BringToFront(); + if (Panel1Minimized && sender == SplitterButton1 && splitterButtonStyle == ButtonStyle.SingleImage) + SplitterButton2.BringToFront(); + else if (Panel2Minimized && sender == SplitterButton2 && splitterButtonStyle == ButtonStyle.SingleImage) + SplitterButton1.BringToFront(); return; } - else if (Panel1Minimized) // Panel 1 - { - SplitterDistance = splitterDistanceOriginal; - Panel1Minimized = false; - } - else // Panel 2 - { - splitterDistanceOriginal = SplitterDistance; - - // When the splitter is vertical, set the location of the splitter to - // the splitcontainer control width minus the minimum size of panel 2. - // For horizontal, set it to height minus panel 2 minimum size - if (Orientation == Orientation.Vertical) SplitterDistance = Width - Panel2MinSize; - else SplitterDistance = Height - Panel2MinSize; - - Panel2Minimized = true; - } } Refresh(); } @@ -383,62 +372,65 @@ private void UpdateSplitterButtonsPosition() int position = GetButtonPosition(); if (Orientation == Orientation.Vertical) { - int width = splitterCollapseDistance == CollapseDistance.Collapsed ? 0 : (Panel1Collapsed ? Panel2.ClientRectangle.Right - splitterButton2.Width : Panel1.ClientRectangle.Right - splitterButton1.Width); + int width = splitterCollapseDistance == CollapseDistance.Collapsed ? 0 : (Panel1Collapsed ? Panel2.ClientRectangle.Right - SplitterButton2.Width : Panel1.ClientRectangle.Right - SplitterButton1.Width); if (splitterCollapseDistance == CollapseDistance.Collapsed || splitterButtonLocation == ButtonLocation.Panel) { - splitterButton1.Location = new Point(width, position); - splitterButton2.Location = new Point(0, position); + SplitterButton1.Location = new Point(width, position); + SplitterButton2.Location = new Point(0, position); } else if (SplitterButtonLocation == ButtonLocation.Panel1) { - splitterButton1.Location = new Point(width, position); - splitterButton2.Location = new Point(width, position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : splitterButton1.Height)); + SplitterButton1.Location = new Point(width, position); + SplitterButton2.Location = new Point(width, position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : SplitterButton1.Height)); } else if (SplitterButtonLocation == ButtonLocation.Panel2) { - splitterButton1.Location = new Point(0, position); - splitterButton2.Location = new Point(0, position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : splitterButton1.Height)); + SplitterButton1.Location = new Point(0, position); + SplitterButton2.Location = new Point(0, position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : SplitterButton1.Height)); } } else { - int height = splitterCollapseDistance == CollapseDistance.Collapsed ? 0 : (Panel1Collapsed ? Panel2.ClientRectangle.Bottom - splitterButton2.Height : Panel1.ClientRectangle.Bottom - splitterButton1.Height); + int height = splitterCollapseDistance == CollapseDistance.Collapsed ? 0 : (Panel1Collapsed ? Panel2.ClientRectangle.Bottom - SplitterButton2.Height : Panel1.ClientRectangle.Bottom - SplitterButton1.Height); if (splitterCollapseDistance == CollapseDistance.Collapsed || splitterButtonLocation == ButtonLocation.Panel) { - splitterButton1.Location = new Point(position, height); - splitterButton2.Location = new Point(position, 0); + SplitterButton1.Location = new Point(position, height); + SplitterButton2.Location = new Point(position, 0); } else if (SplitterButtonLocation == ButtonLocation.Panel1) { - splitterButton1.Location = new Point(position, height); - splitterButton2.Location = new Point(position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : splitterButton1.Width), height); + SplitterButton1.Location = new Point(position, height); + SplitterButton2.Location = new Point(position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : SplitterButton1.Width), height); } else if (SplitterButtonLocation == ButtonLocation.Panel2) { - splitterButton1.Location = new Point(position, 0); - splitterButton2.Location = new Point(position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : splitterButton1.Width), 0); + SplitterButton1.Location = new Point(position, 0); + SplitterButton2.Location = new Point(position + (splitterButtonStyle == ButtonStyle.SingleImage ? 0 : SplitterButton1.Width), 0); } } if (splitterCollapseDistance == CollapseDistance.Collapsed || splitterButtonStyle == ButtonStyle.Image) { - splitterButton1.BringToFront(); - splitterButton2.BringToFront(); + SplitterButton1.BringToFront(); + SplitterButton2.BringToFront(); } else if (SplitterButtonStyle == ButtonStyle.SingleImage) { - if (SingleImageCollapsePanel2) - { - if (Panel2Minimized) splitterButton1.BringToFront(); - else splitterButton2.BringToFront(); - } - else - { - if (Panel1Minimized) splitterButton2.BringToFront(); - else splitterButton1.BringToFront(); - } + if (SingleImageCollapsePanel2) SplitterBtnBringToFront(!Panel2Minimized); + else SplitterBtnBringToFront(Panel1Minimized); + } + } + + private void SplitterBtnBringToFront(bool? Panel1Minimized = null) + { + if (Panel1Minimized == null) + { + SplitterButton1.BringToFront(); + SplitterButton2.BringToFront(); } + if ((bool)Panel1Minimized) SplitterButton2.BringToFront(); + else SplitterButton1.BringToFront(); } /// @@ -448,8 +440,8 @@ private void UpdateSplitterButtonsImage() { if (splitterButtonStyle == ButtonStyle.None) return; - splitterButton1.BackgroundImage = Orientation == Orientation.Vertical ? splitterButtonBitmap : bitmapUp; - splitterButton2.BackgroundImage = Orientation == Orientation.Vertical ? bitmapRight : bitmapDown; + SplitterButton1.BackgroundImage = Orientation == Orientation.Vertical ? splitterButtonBitmap : bitmapUp; + SplitterButton2.BackgroundImage = Orientation == Orientation.Vertical ? bitmapRight : bitmapDown; } #endregion @@ -467,14 +459,14 @@ private int GetButtonPosition() if (Orientation == Orientation.Vertical) { position = rect.Top; - if (splitterButtonPosition == ButtonPosition.Center) position = rect.Bottom / 2 - splitterButton1.Height / 2 - offset / 2; - else if (splitterButtonPosition == ButtonPosition.BottomRight) position = rect.Bottom - splitterButton1.Height - offset; + if (splitterButtonPosition == ButtonPosition.Center) position = rect.Bottom / 2 - SplitterButton1.Height / 2 - offset / 2; + else if (splitterButtonPosition == ButtonPosition.BottomRight) position = rect.Bottom - SplitterButton1.Height - offset; } else { position = rect.Left; - if (splitterButtonPosition == ButtonPosition.Center) position = rect.Right / 2 - splitterButton1.Width / 2 - offset / 2; - else if (splitterButtonPosition == ButtonPosition.BottomRight) position = rect.Right - splitterButton1.Width - offset; + if (splitterButtonPosition == ButtonPosition.Center) position = rect.Right / 2 - SplitterButton1.Width / 2 - offset / 2; + else if (splitterButtonPosition == ButtonPosition.BottomRight) position = rect.Right - SplitterButton1.Width - offset; } return position; } diff --git a/PS4CheaterNeo/lib/GroupGridView.dll b/PS4CheaterNeo/lib/GroupGridView.dll index 987ff67a2d7fcebf44f68880cf7944b0de3a640c..de4de6e90905ca9265fb503c16f6374a6c8a594e 100644 GIT binary patch delta 8770 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 L3qKbv{apV8@cM8J delta 8495 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 diff --git a/README.md b/README.md index a920c8e..bfc69a1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ PS4CheaterNeo is a program to find game cheat codes, and it is based on [`ps4debug`](https://github.com/jogolden/ps4debug) and [`.Net Framework 4.8`](https://support.microsoft.com/en-us/topic/microsoft-net-framework-4-8-offline-installer-for-windows-9d23f658-3b97-68ab-d013-aa3c3e7495e0). -Currently in `version 1.0.2.8` +Currently in `version 1.0.2.9` ## Table of Contents @@ -40,6 +40,10 @@ Currently in `version 1.0.2.8` * [Pointer finder](#pointer-finder) * [Section](#section) + [Section ID](#section-id) + * [Hotkey](#hotkey) + + [main window hotkey](#main-window-hotkey) + + [query window hotkey](#query-window-hotkey) + + [HexEditor window hotkey](#hexeditor-window-hotkey) * [Option](#option) + [General](#general) + [Cheat](#cheat) @@ -526,6 +530,81 @@ AddrStart  Prot count   SIDv1     SID ``` +## Hotkey [🔼](#table-of-contents) + +- Currently, the hotkeys are hardcoded in the program...(1.0.2.9) + +### main window hotkey +- Control + O +Perform open file +- Control + S +Perform save file +- Control + Q +Open Query window +- Control + H +Open HexView window +- Alt + S +Open Settings window +- Control + A +Perform add address +- Control + R +Perform refresh cheat list +- Alt + E +Perform Collapse or ExpandAll in the CheatGridView, automatically determining the current status +- Alt + L +Set LockEnable to enable or disable, depending on the current button activation status +- Alt + R +Set AutoRefresh to enable or disable, depending on the current button activation status + +### query window hotkey +- Control + G +Perform get processes(retrieve all program lists again) +- Control + P +Perform pause or resume. If the current status is paused, execute resume; otherwise, do the opposite +- Alt + S +Perform the first or next scan +- Alt + U +Perform undo scan +- Alt + R +Perform redo scan +- Control + R +Perform refresh result list +- Control + N +Create a new scan, clearing the current scan results +- Alt + C +Clone the current scan results into a new Query window +- Control + Left: +Collapse the left Split panel +- Control + Right: +Expand the left Split panel +- Control + Up: +Collapse the upper right Split panel +- Control + Down: +Expand the upper right Split panel + +### HexEditor window hotkey +- Control + P +Go to Previous Page +- Control + N +Go to Next Page +- Control + R +Refresh HexBox +- Control + S +Write Modifications to PS4 +- Control + A +Add to Cheat Grid +- F3 +Perform Find, forward or backward depending on whether "Forward" is checked +- Control + Left: +Collapse the left Split panel +- Control + Right: +Expand the left Split panel +- Control + Up: +Collapse the upper right Split panel +- Control + Down: +Expand the upper right Split panel + + ## Option [🔼](#table-of-contents) - Added option window, you can adjust some program settings. (0.9.4.0)