powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Выгрузка Ribbon Framework динамически с восстановлением формы
7 сообщений из 7, страница 1 из 1
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39272667
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Речь идет о родном
Windows Ribbon Framework
Использую .Net -обертку, не суть (а м.б. и суть).
Windows Ribbon for WinForms

Идея такая (переделываю старое приложение с классическим меню + Toolbar и т.п.):

1) Дать возможность использовать Ribbon
2) При этом дать возможность использовать старый интерфейс
3) Дать таки пользователю возможность выбирать между (1) Ribbon и (2) Menu+Toolbar

Делаем тест.

1. Загружаю форму обычным образом.
Обычная форма, отображается главное меню (System.Windows.Forms.MainMenu).

2. Стартую Windows Ribbon Framework (нарочно кнопкой и динамически)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
  Dim _ribbon As Ribbon

  Private Sub ButtonLoadRibbon_Click(sender As Object, e As EventArgs) Handles ButtonLoadRibbon.Click
    _ribbon = New Ribbon
    _ribbon.ResourceName = "RibbonTest.RibbonMarkup.ribbon"
    _ribbon.Dock = DockStyle.Top
    Me.Controls.Add(_ribbon)
  End Sub


Все отлично, меню убралось, появился Ribbon

3. А теперь пытаюсь переключиться обратно, как то так:
Код: vbnet
1.
2.
3.
4.
  Private Sub ButtonUnloadRibbon_Click(sender As Object, e As EventArgs) Handles ButtonUnloadRibbon.Click
    _ribbon.Framework.Destroy()
    Me.Controls.Remove(_ribbon)
  End Sub



_ribbon.Framework.Destroy() - так понимаю это
IUIFramework::Destroy method
Terminates and releases all objects, hooks, and references for an instance of the Windows Ribbon framework.

И вот здесь фигня.
Ribbon убрался,
но форма стала инвалидом.
Шапка хоть и отображается, но не функциональна, клинтская область (Panel1 Dock=Fill) похоже "наехала на то место где есть шапка"
Правда если нажать F10;Стрелка вниз,
то меню окна появляется, можно закрыть, минимизировать.
Главное Меню не появилось.
Ну, прога то сама не сдохла, кнопки на ней нажимаются.
Беда только с самим окном.
Как восстановить нормальный классический вид? С шапкой и меню?
М.б. через API? Есть идеи.

P.S. Могу конечно полностью перегружать приложение (при смене режима Ribbon->Классика).
Но неужели нельзя без перестарта?
...
Рейтинг: 0 / 0
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39272721
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Меню конечно восстановить можно например так:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
  Public Declare Function SetMenu Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal hMenu As IntPtr) As Boolean

  Private Sub ButtonUnloadRibbon_Click(sender As Object, e As EventArgs) Handles ButtonUnloadRibbon.Click
    _ribbon.Framework.Destroy()
    Me.Controls.Remove(_ribbon)
    SetMenu(Me.Handle, MainMenu1.Handle)
  End Sub



Но проблема в том, что после де-активации Ribbon Framework
все контролы рисуются от самого верха формы, перекрывая заголовок формы и меню.
Связано скорее всего с реализацией Net-обертки, т.е. в одну сторону грамотно
(клиентская область смещается под Ribbon)
А в другую сторону автор обертки ничего не реализовал
(клиентская область перекрывает шапку)
или я чего-то недопонимаю, как отменить хак, который он делает для риббона.
И как это исправить, копаться в чужих кодах неохота (хотя странно почему само не восстанавливается).

Оптимальный способ чтоб не рушить мозг, видимо предлагать закрыть приложение и запустить снова (без загрузки Ribbon), если уж нужно Main Menu.
...
Рейтинг: 0 / 0
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39272732
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это связано с хромом формы, нужно его установить по новой наверное
...
Рейтинг: 0 / 0
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39272744
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesэто связано с хромом формы, нужно его установить по новой наверное
хром - от слова хромать или что-то английское по-русски написал?
то что что-то надо восстановить (что уезжает при добавлении Ribbon-контрола), это я и так понял, только не понимаю что

что имел ввиду?

Игры с формами (окнами) не так просты, что через API, что через .Net (шаг вправо-влево от "стандартов" -> расстрел)
...
Рейтинг: 0 / 0
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39272864
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Roman Mejtesэто связано с хромом формы, нужно его установить по новой наверное
хром - от слова хромать или что-то английское по-русски написал?
то что что-то надо восстановить (что уезжает при добавлении Ribbon-контрола), это я и так понял, только не понимаю что

что имел ввиду?

Игры с формами (окнами) не так просты, что через API, что через .Net (шаг вправо-влево от "стандартов" -> расстрел)
извини, я ошибся разделом, думал раздел WPF
вот ссылка https://msdn.microsoft.com/en-us/library/system.windows.shell.windowchrome(v=vs.110).aspx
не знаю, возможно у WF приложения всё так же устроено, в чем сильно сомневаюсь.
...
Рейтинг: 0 / 0
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39273276
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes,

Нет, речь не о WPF, а о родном Windows Ribbon Framework, под который сделана неплохая обертка под WinForm,
ссылки в начале первого поста.

Roman Mejtesне знаю, возможно у WF приложения всё так же устроено, в чем сильно сомневаюсь.
Нет конечно,
WinForm -это в основном родной Win32, на который наложена логика макета этих самых WinForm.
Перерисовал картинку.
Логика такова.
1)Делаем форму, на нее кидаем Panel1 (Dock=Fill)
2) При инициализации Ribbon, он "добавляется" на форму как "контрол" с (Dock=Top), но при этом координаты области контролов уже считаются очевидно от самой макушки (а не под ней и главным меню как по стандарту) И скорее всего автор контрола делает какой-то трюк.
3) Когда мы риббон убираем (обычно предполагается закрытие формы, но я этого не делаю), то Panel1 опять занимает место "на всю форму", но это место продолжает быть "от самой макушки" (съехала логика макета).

Возможно вот этот код (из библиотеки риббон-контрола) "портит", но я не уверен
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
        #region Form Windows State change bug workaround
        
        Form _form;
        FormWindowState _previousWindowState;
        int _previousNormalHeight;
        int _preserveHeight;

        void Ribbon_ParentChanged(object sender, EventArgs e)
        {
            var parent = this.Parent;
            if (parent == null)
            {
                RegisterForm(null);
                return;
            }
            var form = parent as Form;
            if (form == null)
                throw new ApplicationException("Parent of Ribbon does not derive from Form class.");

            RegisterForm(form);
        }
        
        void RegisterForm(Form form)
        {
            if (_form != null)
                _form.SizeChanged -= new EventHandler(_form_SizeChanged);

            _form = form;

            if (_form == null)
                return;

            _form.SizeChanged += new EventHandler(_form_SizeChanged);
        }

        void _form_SizeChanged(object sender, EventArgs e)
        {
            if (_previousWindowState != FormWindowState.Normal
                && _form.WindowState == FormWindowState.Normal
                && _previousNormalHeight != 0)
            {
                _preserveHeight = _previousNormalHeight;
                _form.BeginInvoke(new MethodInvoker(RestoreHeight));
            }

            if (_form.WindowState == FormWindowState.Normal)
                _previousNormalHeight = _form.Height;
            _previousWindowState = _form.WindowState;
        }

        void RestoreHeight()
        {
            _form.Height = _preserveHeight;
        }
        #endregion



М.б. через Win API можно подправить, но не знаю куда копать.
...
Рейтинг: 0 / 0
Выгрузка Ribbon Framework динамически с восстановлением формы
    #39275025
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Клиентскую область формы при желании подвинуть можно через WM_NCCALCSIZE
Как-то так в примитиве:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
  <StructLayout(LayoutKind.Sequential)>
  Public Structure RECT
    Dim Left As Integer
    Dim Top As Integer
    Dim Right As Integer
    Dim Bottom As Integer
  End Structure

  <StructLayout(LayoutKind.Sequential)>
  Public Structure WINDOWPOS
    Dim hwnd As IntPtr
    Dim hWndInsertAfter As IntPtr
    Dim x As Integer
    Dim y As Integer
    Dim cx As Integer
    Dim cy As Integer
    Dim Flags As UInteger
  End Structure

  <StructLayout(LayoutKind.Sequential)>
  Public Structure NCCALCSIZE_PARAMS
    Dim rgrc0 As RECT
    Dim rgrc1 As RECT
    Dim rgrc2 As RECT
    Dim lppos As WINDOWPOS
  End Structure

  Dim h_delta As Integer = 0
  Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    'Debug.WriteLine(m.ToString())
    Dim csp As NCCALCSIZE_PARAMS

    Select Case m.Msg
      Case WM_NCCALCSIZE
        If m.WParam = IntPtr.Zero Then
        Else
          If _ribbon Is Nothing Then
            csp = CType(Marshal.PtrToStructure(m.LParam, GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
            csp.rgrc0.Top = csp.rgrc0.Top + h_delta
            Marshal.StructureToPtr(csp, m.LParam, False)
            m.Result = IntPtr.Zero
          End If
        End If
        Debug.WriteLine(m.ToString())
    End Select


    ' Forward message to base WndProc.
    MyBase.WndProc(m)
  End Sub

  Dim _ribbon As Ribbon

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
  End Sub

  Private Sub ButtonUnloadRibbon_Click(sender As Object, e As EventArgs) Handles ButtonUnloadRibbon.Click
    Me.Controls.Remove(_ribbon)
    _ribbon.Framework.Destroy()
    _ribbon = Nothing
    SetMenu(Me.Handle, Me.MainMenu1.Handle)
  End Sub

  Private Sub ButtonLoadRibbon_Click(sender As Object, e As EventArgs) Handles ButtonLoadRibbon.Click
    Dim h_init As Integer = Me.ClientSize.Height
    _ribbon = New Ribbon
    _ribbon.ResourceName = "RibbonTest.RibbonMarkup.ribbon"
    _ribbon.Dock = DockStyle.Top
    _ribbon.TabStop = False
    Me.Controls.Add(_ribbon)
    If h_delta = 0 Then h_delta = Me.ClientSize.Height - h_init
    Debug.Print(h_delta)
  End Sub



Но все одно глючит.
Под меню какая-то глючная полоска (непрорисованный верхний кусок панели и это Refresh-Update опять же не лечится, хотя с кнопками вроде все OK, картинку приложил ниже).
Ну еще восстановление меню через SetMenu имеет свои ньюансы: если уменьшать ширину формы и строка меню займет 2 строчки, то меню наедет на клиентскую область.
Т.е. после убирания риббон-контрола макет все одно поломан, лечи не лечи.

На 7-ке кстати динамическое Me.Controls.Add(_ribbon) тоже подглючивает (на 10-ке нормально), правда лечится переигрыванием
FormWindowState.Normal-> FormWindowState.Minimized ->FormWindowState.Normal

Пожалуй пора забить на этот конкретный вопрос. Через перезагрузку формы вполне достаточно.

Контрол ( Windows Ribbon for WinForms ) супер (главное полностью оборачивает Native), но мелких глюков хватает.
Например когда не все картинки не на всех кнопках добавляются и от чего зависит хз (м.б. уборщик мусора, но вина не моя, проверял) или надписи вовремя не обновляются.
Всякими переигрываниями вроде лечится.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Выгрузка Ribbon Framework динамически с восстановлением формы
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]