Długie renderowanie grafiki w aplikacji

0

Problem polega na tym, że grafiki w aplikacji renderują się dość długo. Przyciski, tło i inne kontrolki tak samo.
(Przepraszam za wstawienie na YT, ale nie miałem innego pomysłu)

Wydaje mi się, że rozwiązaniem może być zaimplementowanie jakiejś biblioteki graficznej, która jakoś wspomogłaby jej renderowanie.

Z góry dziękuję za pomoc.

0

Bez kodu niewiele się da powiedzieć.
Skąd mamy wiedzieć dlaczego działa tak powoli, skoro nie wiemy jak to wszystko rysujesz i co dokładnie robi to menu po lewej.

Tak ze szklanej kuli to mogę wyczytać, że być może w momencie pokazania kontrolek robisz w "tle" (które wcale nie jest tłem) jakieś długotrwałe operacje (pobieranie danych?) i to blokuje główny wątek.

0

Jedyne co mi przychodzi to głowy to to że użyłeś zbyt dużych obrazków (>1MB) jako tła.

Jeżeli przy pokazywaniu okna robisz dużo ustawień to można też:

SuspendLayout();

try
{
    // Update the labels
}
finally
{
    ResumeLayout(performLayout: true);
}

https://stackoverflow.com/questions/52729883/win-forms-label-updates-super-slow

Ewentualnie WinForms ma tylko 1 wątek być może wykonujesz na nim jakieś inne zadania i nie ma czasu na rejestrację labelek.

Najlepiej reprodukuj na mniejszym przykładzie i wrzuć kod...

Ostatnia rzecz testuj przy kompilacji jako Release, być może Debug jest problemem...

0

Kod głównej formy(boczny pasek, przyciski wyłączenia itp...)

using jvPrMacro.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using jvPrMacro.ClickManager;
using jvPrMacro.managers;
using System.Diagnostics;

namespace jvPrMacro
{
    public partial class MainForm : Form
    {
        public static MainForm instance { get; set; }
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();
        public MainForm()
        {
            InitializeComponent();
            instance = this;
            InitializeContextMenu();
            bgWorker.RunWorkerAsync();
        }

        private void form_load(object sender, EventArgs e)
        {
            openChildFormInPanel(new MenuForm());
        }

        private void form_shown(object sender, EventArgs e)
        {
            if (MainClass.instance.runInTray)
            {
                notifyIcon.Visible = true;
                Hide();
            }
        }

        //CONTEXT MENU
        private void InitializeContextMenu()
        {
            MenuItem[] menuList = new MenuItem[]{new MenuItem("Zamknij"), new MenuItem("Otwórz")};
            ContextMenu clickMenu = new ContextMenu(menuList);
            notifyIcon.ContextMenu = clickMenu;

            notifyIcon.Click += new EventHandler(notifyIcon_Click);
        }

        public void notifyIcon_Click(object sender, EventArgs e)
        {
            Size windowSize =
                SystemInformation.PrimaryMonitorMaximizedWindowSize;
            Point menuPoint =
                new Point(windowSize.Width - 180,
                windowSize.Height - 5);
            menuPoint = this.PointToClient(menuPoint);
        }

        private Form activeForm = null;
        private void openChildFormInPanel(Form childForm)
        {
            if (activeForm != null)
                activeForm.Close(); 
            activeForm = childForm;
            childForm.TopLevel = false;
            childForm.FormBorderStyle = FormBorderStyle.None;
            childForm.Dock = DockStyle.Fill;
            panel_child.Controls.Add(childForm);
            panel_child.Tag = childForm;
            childForm.BringToFront();
            childForm.Show();
        }
        private void openChildPanelAtStart()
        {
            if (MainClass.instance.defaultTab == "")
            {

            }
        }

        //BUTTON ANIMATIONS & CLICK EVENTS

            //AUTHORS
        private void btn_authors_MouseEnter(object sender, EventArgs e)
        {
            btn_authors.Image = Properties.Resources.authors_hover;
        }
        private void btn_authors_MouseLeave(object sender, EventArgs e)
        {
            btn_authors.Image = Properties.Resources.authors;
        }
        private void btn_authors_Click(object sender, EventArgs e)
        {
            openChildFormInPanel(new AuthorsForm());
        }

            //MENU
        private void btn_menu_MouseEnter(object sender, EventArgs e)
        {
            btn_menu.Image = Properties.Resources.menu_hover;
        }
        private void btn_menu_MouseLeave(object sender, EventArgs e)
        {
            btn_menu.Image = Properties.Resources.menu;
        }
        private void btn_menu_Click(object sender, EventArgs e)
        {
            openChildFormInPanel(new MenuForm());
        }

            //LEFT CLICK
        private void btn_leftclick_MouseEnter(object sender, EventArgs e)
        {
            btn_leftclick.Image = Properties.Resources.left_button_hover;
        }

        private void btn_leftclick_MouseLeave(object sender, EventArgs e)
        {
            btn_leftclick.Image = Properties.Resources.left_button;
        }

        private void btn_leftclick_Click(object sender, EventArgs e)
        {
            openChildFormInPanel(new LeftClickForm());
        }

        //RIGHT CLICK
        private void btn_rightclick_MouseEnter(object sender, EventArgs e)
        {
            btn_rightclick.Image = Properties.Resources.right_button_hover;
        }

        private void btn_rightclick_MouseLeave(object sender, EventArgs e)
        {
            btn_rightclick.Image = Properties.Resources.right_button;
        }

        private void btn_rightclick_Click(object sender, EventArgs e)
        {
            openChildFormInPanel(new RightClickForm());
        }

        //KEYBOARD
        private void btn_keyboard_MouseEnter(object sender, EventArgs e)
        {
            btn_keyboard.Image = Properties.Resources.keyboard_hover;
        }

        private void btn_keyboard_MouseLeave(object sender, EventArgs e)
        {
            btn_keyboard.Image = Properties.Resources.keyboard;
        }

        private void btn_keyboard_Click(object sender, EventArgs e)
        {

        }

        //TOP PANEL - moving aplication
        private void panel_top_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }

        //CLOSE BUTTON
        private void btn_close_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        private void btn_close_MouseEnter(object sender, EventArgs e)
        {
            btn_close.Image = Properties.Resources.close_button_hover;
        }

        private void btn_close_MouseLeave(object sender, EventArgs e)
        {
            btn_close.Image = Properties.Resources.close_button;
        }

        //MINIMIZE BUTTON
        private void btn_minimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }
        private void btn_minimize_MouseEnter(object sender, EventArgs e)
        {
            btn_minimize.Image = Properties.Resources.minimalize_button_hover;
        }

        private void btn_minimize_MouseLeave(object sender, EventArgs e)
        {
            btn_minimize.Image = Properties.Resources.minimalize_button;
        }

        //HIDE APLICATION(SYSTEM TRAY)
        private void btn_minimizeToTray_Click(object sender, EventArgs e)
        {
            notifyIcon.Visible = true;
            Hide();
            if (MainClass.instance.notifications) 
                notifyIcon.ShowBalloonTip(500, "JVPRMacro", "Pomyślnie schowano\ndo paska aplikacji!", ToolTipIcon.Info);
        }
        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            notifyIcon.Visible = false;
            Show();
        }
        private void btn_minimizeToTray_MouseEnter(object sender, EventArgs e)
        {
            btn_minimizeToTray.Image = Properties.Resources.hide_button_hover;
        }

        private void btn_minimizeToTray_MouseLeave(object sender, EventArgs e)
        {
            btn_minimizeToTray.Image = Properties.Resources.hide_button;
        }



        async void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (Keyboard.IsKeyDown(Keys.X)) {
                    if (MainClass.instance.windowChecking)
                    {
                        if (FocusMonitor.instance.name == MainClass.instance.windowName)
                        {
                            LeftClickManager.instance.click();
                            await Task.Delay(MainClass.instance.leftClickIntervals);
                        }
                    }
                    else
                    {
                        LeftClickManager.instance.click();
                        await Task.Delay(MainClass.instance.leftClickIntervals);
                    }
                }
            }
        }
    }
}

MenuForm(Najdluzej ladujaca sie zakladka)

using jvPrMacro.managers;
using jvPrMacro.Managers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;

namespace jvPrMacro.Forms
{
    public partial class MenuForm : Form
    {
        
        public static MenuForm instance { get; set; }
        public MenuForm()
        {
            instance = this;
            DiscordStatusManager.instance.initialize();
            if (MainClass.instance.discordStatus)
            {
                DiscordStatusManager.instance.setPresence();
            }
            InitializeComponent();
        }

        private void MenuForm_Load(object sender, EventArgs e)
        {
            if (DataManager.instance.getList().Count > 0) { 
                 cb_listOfWindowNames.DataSource = DataManager.instance.getList();
            }
            cb_defaultTab.SelectedItem = MainClass.instance.defaultTab;
            txt_windowName.Text = MainClass.instance.windowName;
            cb_window.Checked = MainClass.instance.windowChecking;
            cb_notifications.Checked = MainClass.instance.notifications;
            cb_autostart.Checked = MainClass.instance.autostart;
            cb_discordStatus.Checked = MainClass.instance.discordStatus;
            cb_showTimeInRpc.Checked = MainClass.instance.showTimeInRpc;
            cb_runInTray.Checked = MainClass.instance.runInTray;
            Process[] processlist = Process.GetProcesses();
            foreach (Process process in processlist)
            {
                if (!String.IsNullOrEmpty(process.MainWindowTitle))
                {
                    cb_quickAddWindowName.Items.Add(process.MainWindowTitle);
                }
            }
        }

        private void txt_windowName_MouseClick(object sender, MouseEventArgs e)
        {
            panel_windowNameUnder.BackColor = Color.White;
        }

        private void txt_windowName_Leave(object sender, EventArgs e)
        {
            panel_windowNameUnder.BackColor = Color.Gray;
            var text = txt_windowName.Text;
            if (text == null || text == "" || text == " ")
            {
                txt_windowName.Text = Properties.Settings.Default.windowName;
                return;
            }
            MainClass.instance.windowName = text;
            Properties.Settings.Default.windowName = text;
            Properties.Settings.Default.Save();
        }

        private void txt_windowName_textChanged(object sender, EventArgs e)
        {
            var text = txt_windowName.Text;
            if (text == null || text == "" || text == " ")
            {
                txt_windowName.Text = Properties.Settings.Default.windowName;
                return;
            }
            MainClass.instance.windowName = text;
            Properties.Settings.Default.windowName = text;
            Properties.Settings.Default.Save();
        }

        private void cb_window_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_window.Checked)
            {
                Properties.Settings.Default.windowChecking = true;
                MainClass.instance.windowChecking = true;
            }
            else
            {
                MainClass.instance.windowChecking = false;
                Properties.Settings.Default.windowChecking = false;
            }
            Properties.Settings.Default.Save();
        }

        private void cb_showTimeInRpc_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_showTimeInRpc.Checked)
            {
                MainClass.instance.showTimeInRpc = true;
                Properties.Settings.Default.showTimeInRpc = true;
            }
            else
            {
                MainClass.instance.showTimeInRpc = false;
                Properties.Settings.Default.showTimeInRpc = false;
            }
            DiscordStatusManager.instance.setPresence();
            Properties.Settings.Default.Save();
        }

        private void cb_notifications_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_notifications.Checked)
            {
                MainClass.instance.notifications = true;
                Properties.Settings.Default.notifications = true;
            }
            else
            {
                MainClass.instance.notifications = false;
                Properties.Settings.Default.notifications = false;
            }
            Properties.Settings.Default.Save();
        }

        private void cb_discordStatus_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_discordStatus.Checked)
            {
                MainClass.instance.discordStatus = true;
                DiscordStatusManager.instance.setPresence();
                Properties.Settings.Default.discordStatus = true;
                cb_showTimeInRpc.Visible = true;
            }
            else
            {
                MainClass.instance.discordStatus = false;
                DiscordStatusManager.instance.clearPresence();
                Properties.Settings.Default.discordStatus = false;
                cb_showTimeInRpc.Visible = false;
            }
            Properties.Settings.Default.Save();
        }

        private void cb_autostart_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_autostart.Checked)
            {
                MainClass.instance.autostart = true;
                StartupManager.EnableStartup();
                Properties.Settings.Default.autoStart = true;
            }
            else
            {
                MainClass.instance.autostart = false;
                StartupManager.DisableStartup();
                Properties.Settings.Default.autoStart = false;
            }
            Properties.Settings.Default.Save();
        }

        private void btn_remove_Click(object sender, EventArgs e)
        {
            if (cb_listOfWindowNames.SelectedItem != null)
            {
                string toRemove = cb_listOfWindowNames.SelectedItem.ToString();
                DataManager.instance.removeListElement(toRemove);
                if (DataManager.instance.getList().Count > 0)
                {
                    cb_listOfWindowNames.DataSource = DataManager.instance.getList();
                }
            }
            
        }

        private void btn_save_Click(object sender, EventArgs e)
        {
            string toSave = txt_windowName.Text;
            if (!DataManager.instance.getList().Contains(toSave))
            {
                DataManager.instance.addListElement(toSave);
                cb_listOfWindowNames.DataSource = DataManager.instance.getList();
            }
        }

        private void btn_load_Click(object sender, EventArgs e)
        {
            if (cb_listOfWindowNames.SelectedItem != null)
            {
                var toSave = cb_listOfWindowNames.SelectedItem.ToString();
                txt_windowName.Text = toSave;
                Properties.Settings.Default.windowName = toSave;
                MainClass.instance.windowName = toSave;
            }
        }

        private void cb_quickAddWindowName_SelectedValueChanged(object sender, EventArgs e)
        {
            string toSave = cb_quickAddWindowName.SelectedItem.ToString();
            if (!DataManager.instance.getList().Contains(toSave))
            {
                DataManager.instance.addListElement(toSave);
                cb_listOfWindowNames.DataSource = DataManager.instance.getList();
                txt_windowName.Text = cb_quickAddWindowName.SelectedItem.ToString();
                cb_listOfWindowNames.SelectedItem = toSave;
                txt_windowName.Text = toSave;
                Properties.Settings.Default.windowName = toSave;
                MainClass.instance.windowName = toSave;
            }
        }

        private void cb_quickAddWindowName_DropDown(object sender, EventArgs e)
        {
            Process[] processlist = Process.GetProcesses();
            foreach (Process process in processlist)
            {
                if (!String.IsNullOrEmpty(process.MainWindowTitle))
                {
                    if(!cb_quickAddWindowName.Items.Contains(process.MainWindowTitle) && process.MainWindowTitle!="JVPRMACRO")
                        cb_quickAddWindowName.Items.Add(process.MainWindowTitle);
                }
            }
        }

        private void cb_defaultTab_SelectedValueChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.defaultTab = cb_defaultTab.SelectedItem.ToString();
            Properties.Settings.Default.Save();
        }

        private void cb_runInTray_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_runInTray.Checked)
            {
                MainClass.instance.runInTray = true;
                Properties.Settings.Default.runInTray = true;
            }
            else
            {
                MainClass.instance.runInTray = false;
                Properties.Settings.Default.runInTray = false;
            }
            Properties.Settings.Default.Save();
        }
    }
}

Przepraszam, że od razu tego nie zrobilem, ale bylem juz zmeczony i nie pomyslalem, ze moze sie to przydac

0

Na oko:

Process[] processlist = Process.GetProcesses();

zabiera dużo czasu, wrzuć to w background workera.

Generalnie jeżeli problem się reprodukuje na prostszym przykładzie, to albo użyj profilera albo komentuj kolejne metody aż program zacznie szybciej działać. W ten sposób ustalisz wąskie gardło. Nie wiem na ile Profiler będzie dobry dla applikacji GUI, warto więc sięgnąć po stare dobre logowanie i zalogować w try finally czas wykonania wszystkich kroków w Form Load i konstruktorze.

0

@0xmarcin: wyrzuciłem kompletnie ta metode, i tak lista procesów jest pobierana podczas eventu DropDown

private void cb_quickAddWindowName_DropDown(object sender, EventArgs e)
        {
            Process[] processlist = Process.GetProcesses();
            foreach (Process process in processlist)
            {
                if (!String.IsNullOrEmpty(process.MainWindowTitle))
                {
                    if(!cb_quickAddWindowName.Items.Contains(process.MainWindowTitle) && process.MainWindowTitle!="JVPRMACRO")
                        cb_quickAddWindowName.Items.Add(process.MainWindowTitle);
                }
            }
        }

Wszystko co się da zrobiłem przed załadowaniem formy samej w sobie:

        public MenuForm()
        {
            InitializeComponent();
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            instance = this;

            if (DataManager.instance.getList().Count > 0)
            {
                cb_listOfWindowNames.DataSource = DataManager.instance.getList();
            }
            cb_defaultTab.SelectedItem = MainClass.instance.defaultTab;
            txt_windowName.Text = MainClass.instance.windowName;
            cb_window.Checked = MainClass.instance.windowChecking;
            cb_notifications.Checked = MainClass.instance.notifications;
            cb_autostart.Checked = MainClass.instance.autostart;
            cb_discordStatus.Checked = MainClass.instance.discordStatus;
            cb_showTimeInRpc.Checked = MainClass.instance.showTimeInRpc;
            cb_runInTray.Checked = MainClass.instance.runInTray;
        }

(wszystkie te elementy były w metodzie Load)

Ale nadal wydaje mi się, że mogłoby się to renderować szybciej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1