Faq каким образом можно изменить системное меню формы


Содержание

Программирование Delphi

Все о программировании.

Главное меню

Изменение системного меню

С помощью API Windows мы можем настраивать системное меню формы. Так, например, мы можем добавить свой пункт меню или удалить уже имеющийся, изменить пункт меню по умолчанию и даже добавить растровое изображение.

Для того, чтобы получить доступ к системному меню, нужно использовать функцию GetSystemMenu API Windows. Также далее мы будем использовать AppendMenu, SetMenuItemInfo, а также структуру TMenuItemInfo. После добавления своего пункта меню, нужно добавить ловушку на сообщение WM_SYSCOMMAND, чтобы узнать, когда будет выбран наш пункт меню.

Добавление пункта меню

Следующий код демонстрирует исользование функции AppendMenu для добавления нового пункта в системное меню формы. Для начала, нам нужно определить новую константу SC_MyMenuItem, которая будет идентифицировать наш новый пункт меню.

После добавления пункта меню, мы должны отловить сообщение WM_SYSCOMMAND для обработки щелчка.

Примечание: при сворачивании приложения, значок представляет собой приложение, а не форму. Поэтому, чтобы измененное меню работало и в свернутом виде, нужно использовать Application.Handle, а не просто Handle, когда будете добавлять свой пункт меню.

Удаление системного пункта меню

При удалении пункта системного меню, мы также удаляем возможность выполнения его из системного меню формы. При помощи DeleteMenu давайте удалим пункт Переместить.

Обратите внимание: после удаления этого пункта меню, мы не сможем больше перемещать форму. Это не самый лучший способ удаления меню.

Изменение заголовка пункта меню

Чтобы изменить заголовок пункта системного меню, мы должны вызвать функцию SetMenuItemInfo и отправить ей структуру TMenuItemInfo, которая содержит информацию о пункте меню.

Давайте изменим заголовок пункта меню Закрыть.

Добавление изображения в пункт меню

Для этого выберите изображение в формате bmp и поместите его в папку с проектом. Я взял изображение, которое идет вместе с Delphi и находится в папке Program Files\Common Files\Borland Shared\Images\Icons и называется CHEM16.BMP .

Запишите следующий код:

Вот и все по работе с системным меню формы нашего приложения.

Пошаговое руководство. Связывание стандартных элементов меню с формой Walkthrough: Providing Standard Menu Items to a Form

С помощью элемента управления MenuStrip можно создавать стандартные меню для форм. You can provide a standard menu for your forms with the MenuStrip control.

В этом пошаговом руководстве демонстрируется использование MenuStrip элементу управления создавать стандартные меню. This walkthrough demonstrates how to use a MenuStrip control to create a standard menu. Также форма изменяется при выборе пользователем пункта меню. The form also responds when a user selects a menu item. В этом пошаговом руководстве показаны следующие задачи: The following tasks are illustrated in this walkthrough:

Создание проекта Windows Forms. Creating a Windows Forms project.

Создание стандартного меню. Creating a standard menu.

Создание StatusStrip элемента управления. Creating a StatusStrip control.

Управление выбором элементов меню. Handling menu item selection.

Когда вы закончите, вы получите формы, содержащей стандартное меню, в котором отображаются выбранные элементы меню в StatusStrip элемента управления. When you are finished, you will have a form with a standard menu that displays menu item selections in a StatusStrip control.

Чтобы скопировать код из этого раздела единым блоком, см. раздел Практическое руководство. Обеспечивают стандартные пункты меню к форме. To copy the code in this topic as a single listing, see How to: Provide Standard Menu Items to a Form.

Предварительные требования Prerequisites

Вам потребуется Visual Studio для выполнения этого пошагового руководства. You’ll need Visual Studio to complete this walkthrough.

Создание проекта Create the project

В Visual Studio создайте проект приложения Windows с именем StandardMenuForm (файл > New > проекта > Visual C# или Visual Basic > классический рабочий стол > Windows Forms Application). In Visual Studio, create a Windows application project called StandardMenuForm (File > New > Project > Visual C# or Visual Basic > Classic Desktop > Windows Forms Application).

В конструкторе Windows Forms выберите форму. In the Windows Forms Designer, select the form.

Создание стандартного меню Create a standard menu

В конструкторе Windows Forms позволяет автоматически заполнять MenuStrip элемента управления с помощью стандартных элементов меню. The Windows Forms Designer can automatically populate a MenuStrip control with standard menu items.

Из элементов, перетащите MenuStrip управления на форму. From the Toolbox, drag a MenuStrip control onto your form.

Нажмите кнопку MenuStrip глиф смарт-тега элемента управления ( ) и выберите вставить стандартные элементы. Click the MenuStrip control’s smart tag glyph ( ) and select Insert Standard Items.

MenuStrip Заполнением стандартные пункты меню элемента управления. The MenuStrip control is populated with the standard menu items.

Нажмите кнопку файл элемент меню, чтобы увидеть его элементы меню по умолчанию и соответствующие значки. Click the File menu item to see its default menu items and corresponding icons.


Создание элемента управления StatusStrip Create a StatusStrip control

Используйте StatusStrip управления для отображения состояния для приложений Windows Forms. Use the StatusStrip control to display status for your Windows Forms applications. В этом примере элементы меню, выбранный пользователем отображаются в StatusStrip элемента управления. In the current example, menu items selected by the user are displayed in a StatusStrip control.

Из элементов, перетащите StatusStrip управления на форму. From the Toolbox, drag a StatusStrip control onto your form.

StatusStrip Автоматически прикреплен к нижней части формы. The StatusStrip control automatically docks to the bottom of the form.

Нажмите кнопку StatusStrip кнопку раскрывающегося списка элемента управления и выберите StatusLabel добавление ToolStripStatusLabel управления StatusStrip элемента управления. Click the StatusStrip control’s drop-down button and select StatusLabel to add a ToolStripStatusLabel control to the StatusStrip control.

Управлять выбором элементов Handle item selection

Обрабатывать DropDownItemClicked событий, чтобы ответить, когда пользователь выбирает пункт меню. Handle the DropDownItemClicked event to respond when the user selects a menu item.

Нажмите кнопку файл пункт меню, который вы создали при создании стандартного раздела меню. Click the File menu item that you created in the Creating a Standard Menu section.

В окне Свойства выберите События. In the Properties window, click Events.

Дважды щелкните DropDownItemClicked событий. Double-click the DropDownItemClicked event.

В конструкторе Windows Forms создает обработчик событий для DropDownItemClicked событий. The Windows Forms Designer generates an event handler for the DropDownItemClicked event.

Вставьте следующий код в обработчик событий. Insert the following code into the event handler.

Вставить UpdateStatus определение служебного метода в форму. Insert the UpdateStatus utility method definition into the form.

CHECKPOINT-тестирования в форму Checkpoint -test your form

Нажмите клавишу F5 для компиляции и запуска в форму. Press F5 to compile and run your form.

Нажмите кнопку файл пункт меню, чтобы открыть меню. Click the File menu item to open the menu.

На файл меню, выберите один из элементов, чтобы выбрать его. On the File menu, click one of the items to select it.

StatusStrip Элемент управления отображает выбранный элемент. The StatusStrip control displays the selected item.

Следующие шаги Next steps

В этом пошаговом руководстве вы создали формы, содержащей стандартное меню. In this walkthrough, you have created a form with a standard menu. Можно использовать ToolStrip семейства элементов управления, для многих других целей: You can use the ToolStrip family of controls for many other purposes:

Создать контекстное меню для элементов управления с ContextMenuStrip. Create shortcut menus for your controls with ContextMenuStrip. Дополнительные сведения см. в разделе Общие сведения о компоненте ContextMenu. For more information, see ContextMenu Component Overview.

Создайте форму многодокументного интерфейса (MDI) закрепленный ToolStrip элементов управления. Create a multiple document interface (MDI) form with docking ToolStrip controls. Дополнительные сведения см. в разделе Пошаговое руководство: Создание формы MDI путем слияния меню и элементов управления ToolStrip. For more information, see Walkthrough: Creating an MDI Form with Menu Merging and ToolStrip Controls.

Предоставить вашей ToolStrip управляет профессиональный вид. Give your ToolStrip controls a professional appearance. Дополнительные сведения см. в разделе Как Назначение средства визуализации компоненту ToolStrip для приложения. For more information, see How to: Set the ToolStrip Renderer for an Application.

Урок 18. Системное меню

На этом уроке изучим системное меню. Сейчас мы с вами посмотрим, как можно в вашем приложении изменить системное меню. Это меню, как известно, появляется при нажатии на иконке в левом верхнем углу вашего приложения.

Часто для небольшого приложения вполне достаточно изменения только этого меню (если вам всего надо добавить только 1-2 пункта в ваше приложение). Для изменения этого меню мы должны использовать API-функцию InsertMenu . Также нам пригодится API-функция GetSystemMenu — она возвращает указатель на системное меню.

Вот конкретный пример кода:

InsertMenu(menu, 5, MF_ByPosition, 1000, ‘About’);

Этот код надо поместить, например, в обработчик нажатия кнопки (при нажатии на которую и будет добавляться в системное меню новый пункт). Разумеется, переменная menu типа HMENU должна быть до этого определена.

Параметры у функции InsertMenu следующие: первый — это указатель на системное меню. Его мы получили через API-функцию GetSystemMenu . Второй — это номер позиции, на которую наш новый пункт меню вставится (нумерация идет с нуля). Значение третьего параметра ( MF_ByPosition ) говорит о том, что второй параметр интерпретируется именно как номер позиции для нового пункта меню. Четвертый — это идентификатор меню (мы задали для него значение 1000). И, наконец, пятый — это заголовок нового пункта меню.

Илон Маск рекомендует:  Что такое код write

При запуске программы и нажатии на кнопку с добавленный в ее обработчик кодом в системном меню появится новый пункт:

Сейчас при выборе этого пункта ничего не происходит. Давайте добавим обработчик. Для этого вносим объявление нового обработчика в соответствующее место кода нашей формы.

rocedure SystemMenu(var Msg:TMessage); Message WM_SysCommand;

Далее пишем сам обработчик :

procedure TForm1.SystemMenu(var Msg:TMessage);

if Msg.wParam=1000 Then // если выбрали меню с идентификатором 1000

Теперь при выборе нашего пункта меню естественно появится messagebox «О программе . «.

Системное меню 1С, системные кнопки, как убрать?

(24) > — к чему это?
Дык нормальные люди другим нормальным предлагают нормально оттестированный продукт.


> Но знаю — можно..
Дык все можно, если очень захотеть.

ЗЫ. Неправильный путь наметил. Все проще.

(36) просто если 1С что-то не может, то может и не стоит ее мучать. намного проще и НАДЕЖНЕЙ сделать такую штуку на другом языке. по уровню ближе всего .NET

(42) я понял, но тем не менее.

я свое пытаюсь делать на уровне семерки (со стороны разработчика), т.е. пытаюсь максимально упростить конфигурирование, но при этом, не закрывая возможностей C#.

но, кажется, (0) нужно простейшее меню с большими кнопками. и доступом к БД. а это легко организуется на .NET, Delphi, VB

Как настроить системное меню формы Windows?

Я хочу добавить пункт меню «возраст» в мое приложение. Я хочу добавить его в «системное меню» приложения (тот, который появляется, когда мы нажимаем значок приложения в левом верхнем углу). Итак, как я могу это сделать в .NET?

5 ответов

Windows позволяет довольно легко получить дескриптор копии системного меню формы для целей настройки с помощью GetSystemMenu функции. Трудная часть заключается в том, что вы самостоятельно выполняете соответствующие изменения в возвращаемом меню, используя такие функции, как AppendMenu , InsertMenu и DeleteMenu так же, как если бы вы программировали непосредственно против Win32 API.

однако, если все, что вы хотите сделать это добавить простой пункт меню, это действительно не так сложно. Например, вам нужно будет использовать только AppendMenu функция, потому что все, что вы хотите сделать, это добавить элемент или два в конец меню. Выполнение чего-либо более продвинутого (например, вставка элемента в середине меню, отображение растрового изображения в элементе меню, отображение элементов меню, Установка элемента меню по умолчанию и т. д.) требует немного больше работы. Но как только вы узнаете, как это делается, вы можете сойти с ума. The документация по меню функции говорит все.

вот полный код для формы, которая добавляет разделительную строку и пункт «о программе» в нижней части своего системного меню (также называемого меню окна):

и вот как выглядит готовый продукт:

Я взял решение Коди Грея еще на один шаг и сделал из него многоразовый класс. Это часть моего инструмента отправки журнала приложений, который должен скрывать информацию о нем в системном меню.

его можно легко использовать следующим образом:

значение-add довольно мало для количества pinvoke вам понадобится. Но это возможно. Используйте GetSystemMenu () для извлечения дескриптора системного меню. Затем InsertMenuItem добавить запись. Вы должны сделать это в переопределении OnHandleCreated (), чтобы воссоздать меню, когда окно будет воссоздано.

переопределите WndProc (), чтобы распознать сообщение WM_SYSCOMMAND, которое создается при щелчке пользователя. Визит pinvoke.net для деклараций pinvoke вам понадобится.

Я знаю, что этот ответ старый, но мне очень понравился ответ LonelyPixel. Однако, это нужно для правильной работы с WPF. Ниже приведена версия WPF, которую я написал, поэтому вам не нужно :).

Классы

fsStayOnTop

От: Philip Kapusta 74170,3550

Почему, если присвоить свойству FormStyle значение fsStayOnTop, форма так и не остается на самом верху?

Просто добавьте application.RestoreTopMosts в обработчик события формы OnPaint. Это ошибка.

Могли бы вы рассказать об этом чуть-чуть поподробнее? Delphi где-то в неправильном месте осуществляет вызов NormalizeTopMosts?

Borland говорит что это Windows, но это случается когда StayonTop-форма НЕ является главной формой. (Некоторые английские программисты чтобы получить эту отговорку потратили несколько сотен долларов, звоня в американскую службу помощи по телефону 1-800).

Без иконки в панели задач?

Если вы не хотите, чтобы ваше приложение имело иконку в панели задач, добавьте следующие строки в исходный код проекта:

Да, чуть не забыл, есть еще одна вещь. При нормальном поведении TApplication создает дескриптор и показывает окно прежде, чем далее начнет что-то «происходить». Чтобы избежать этого, вам необходимо создать модуль, содержащий единственную строчку в секции initialization:

… и поместить этот модуль ПЕРВЫМ в .DPR-файле в списке используемых модулей. Этим мы «одурачиваем» TApplication, и оно думает что оно запущено из DLL, тем самым изменяя свое обычное поведение.

– Neil J. Rubenking

Передача переменных форме

…поможете мне создать функцию, с помощью которой я передам переменные в TFormClass? Проблема в том, что MyDlg.Execute() не захотела компилироваться, поскольку, как сообщил мне компилятор, я не могу использовать MyDlg (определенный как: TForm).

Эта функция может выглядеть примерно так:

function ExecuteDialog(FormClass: TFormClass; var Data): Boolean;

Я могу вам дать еще один совет: сделать все ваши формы наследниками одного класса, в котором объявлены виртуальные методы SetData и GetData.

function ExecuteDialog(FormClass: TExecFormClass; var Data): Boolean;

function ExecuteDialog(FormClass: TExecFormClass; var Data): Boolean;

Как вы можете видеть, я поместил функцию ExecuteDialog в тот же самый модуль.

После того как Delphi создаст форму, вы должны в модуле формы сделать четыре вещи:


1. вручную измените предка формы, с TForm на TExecForm;

2. добавьте ExecFrms в список используемых модулей;

3. добавьте тип записи для хранения данных, необходимых диалогу; и

4. перекрыть методы SetData и GetData.

uses WinTypes, WinProcs, Classes, Graphics, Forms,Controls, Buttons, StdCtrls, Spin, ExtCtrls, ExecFrms;

Затем создаем и выполняем диалог, который должен выглядеть приблизительно так:

procedure TForm1.GetNewCaptionAndWidthBtnClick(Sender: TObject);

if ExecuteDialog(TMyDlg, Data) then begin

Не поверите: данный код работает еще со времён Turbo Vision!

Освобождение экземпляров формы

В нашем примере для решения задачи мы передаем конструктору переменную формы. Затем, при закрытии формы, мы сбрасываем эту переменную.

Естественно, эта технология подразумевает написание некоторого кода, поэтому, если вы не расположены к этому действию, пропустите мое дальнейшее повествование.

constructor Create(AOwner: TComponent; var AFormVar: TMyForm);

constructor TMyForm.Create(AOwner: TComponent; var AFormVar: TMyForm);

MyOtherForm := TMyForm.Create(Self, MyOtherForm);

Этот код при разрушении окна автоматически сбрасывает все, что вы передаете в AFormVar, в nil.

Как вы, наверное, заметили, частный член FormVar реально является указателем на указатель. Так, читая содержимое памяти, адрес которой содержится в FormVar, мы реально получаем переменную формы. Таким образом мы можем просто установить ее в nil.

Условие создания главной формы?

Существует ли в Delphi возможность создавать главную форму по условию? Я хочу использовать условие IF (в зависимости от передаваемого параметра) для того, чтобы определить какая форма будет главной при старте приложения. Фактически «другую» форму НЕ нужно будет загружать.

Хитрость здесь заключается в том, что мы предоставляем компилятору весь необходимый для создания форм код, но не допускаем его выполнения (IF FALSE THEN), при этом компилятор не ругается, а мы тем временем (во время выполнения приложения) выбираем и создаем главную форму. Вот пример кода, измененный .DPR-файл, который при старте случайным образом выбирает из друх форм главную:

// эти 2 строчки позволят нам не выходить за границы

Шаг 3. Добавьте формы 1 и 2 (и любые другие, какие вы хотите иметь) в список используемых модулей формы mainform.

Шаг 4. В форме Form1 и Form2 добавьте MainForm в список используемых модулей (чтобы они видели константы.)

Шаг 5. На форму Form1, Form2, и все последующие, добавьте 2 TBitBtn’а, с заголовками «Next» и «Previous». In the Onclick Events for these buttons add the following line of code.

Если это кнопка Next, добавьте: ModalResult := mrNext;

Если это кнопка Previous, добавьте: ModalResult := mrPrevious;

Как заставить формы минимизироваться на панель задач с анимацией?

Дело-то вот в чем: Главным окном программы дельфийской является не главная форма, а окно TApplication, которое имеет нулевые размеры, поэтому его не видно. Именно для него показывается иконка на панели задач. Когда пользователь нажимает кнопку минимизации на главной форме, команда минимизации передается этому окну, и сворачивается именно оно, а для остальных просто делается hide. А так как окно TApplication имеет нулевые размеры, то и анимации никакой не видно.

А чтобы этого избежать, необходимо:

В исходном тесте модуля проекта после вызова Application.Initialize выполнить вызов

// В исходном тесте модуля проекта после вызова Application.Initialize

SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);

В исходном тексте модуля главной формы перекрыть следующие методы –

procedure CreateParams(var p: TCreateParams); override;

procedure WMSysCommand(var m: TMessage); message WM_SYSCOMMAND;

procedure TMainForm.CreateParams(var p: TCreateParams);

m.Result := DefWindowProc(Handle, m.Msg, m.wParam, m.lParam);

Вместо SetWindowLong в MDI-приложениях лучше использовать

Перемещение формы не за заголовок III


В следующем примере показано как можно передвигать форму если пользователь «захватил» Client-пространство:

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);

procedure TForm1.Button1Click(Sender: TObject);

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

Перемещение формы не за заголовок IV

Как мне переместить форму, не имеющую заголовка?

Выберите элемент управления (или саму форму) и напишите это в его (ее) обработчике события OnMouseDown (данный пример дан только для формы):

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

Классно! Намного проще метода NCHitTest, который я предлагал. Хотя многое из того, чтобы вы мне написали, я не понял. Для чего нужно прибавлять 2 к параметру SC_MOVE? В справке по API об этом ничего не сказано.

Ну хорошо, есть недокументированный способ сообщить Windows о необходимости перемещения окна таким же способом, что и с помощью заголовка (это может вызвать неадекватную реакцию системы, не делайте этого!). Другим способом перемещения окна является перекрытие WMNCHITTEST и возвращения им значения HTCAPTION. Тем не менее, обычно я предпочитаю пользоваться методом SC_MOVE+2, поскольку он не требует создания потомков, а только создание обработчика OnMouseDown. Отчасти аналогично, вы можете добавлять константы SC_SIZE к WM_SYSCOMMAND для получения размера окна подобно тому, как если бы вы потянули его за бордюрчик. В основном мы добавляем код hittest – 9. В следующем классе определена панель, которая сама изменяет свои размеры при щелчке в ее нижнем правом углу, и сама перемещается, если вы щелкнули по ней где-то еще.

Procedure wmNCHitTest(Var Message : TWMNCHitTest); message WM_NCHITTEST;

Procedure MouseDown(Button : TMouseButton; Shift : TShiftState; X, Y : Integer); override;

Procedure TMovablePanel.wmNCHitTest(Var Message : TWMNCHitTest);

unit Unit2; //главная форма проекта; содержит первую страницу

interface //и кнопки Cancel, Prev & Next/Finish.

procedure TPagesDlg.AddForms; //размещение динамических страниц

for i:= 0 to 1 do TBPgFrm(Frms[i]).TabSheet1.PageControl := PageControl1

procedure TPagesDlg.CancelBtnClick(Sender: TObject);

procedure TPagesDlg.FormDestroy(Sender: TObject);

procedure TPagesDlg.NextClick(Sender: TObject);

ActivePage:= FindNextPage(ActivePage, True, false);

if ActivePage.PageIndex=PageCount-1 then Next.Caption:= ‘Finish’;

procedure TPagesDlg.PrevClick(Sender: TObject);

ActivePage:= FindNextPage(ActivePage, false, false);

В Delphi 4 появились новые возможности, в частности, возможность докинга визуальных компонент, в частности, форм, на различные DockSite, в том числе и на TPageControl. Это более удобно. Кроме того, Вы имеете возможность использования TFormLoader из библиотеки VG Library.

Илон Маск рекомендует:  Секреты печати из программы на delphi

IMHO файл *.dfm – это компилированный ресурс с определением установок формы. А можно ли как-то увидеть этот ресуpс в исходном виде?

1. File|Open… ТвояФорма.DFM – увидишь текст;

2. «Delphi\bin\convert ТвояФорма.DFM» — получится ТвояФорма.TXT (можно и наоборот).

Идею в массы: в DN/VC/NC можно настроить viewer’ом .DFM .BAT’ник, который скажет convert;wpview;del – и заглядывать в .DFM не открывая Delphi.

Кстати, функции, которые реализуют это преобразование, доступны для использования в личных целях :)

procedure ObjectBinaryToText(Input, Output: TStream);

procedure ObjectTextToBinary(Input, Output: TStream);

procedure ObjectResourceToText(Input, Output: TStream);

procedure ObjectTextToResource(Input, Output: TStream);

Определение перемещения формы

Кто-нибудь знает как мне определить перемещение пользователем главной формы приложения (не изменение ее размеров), кроме как использования таймера и проверки значений свойств Form.Top и Form.Left?

Вам можно воспользоваться обработчиками следующих системных сообщений:

1. WM_WINDOWPOSCHANGING (возникает перед перемещением),


2. WM_WINDOWPOSCHANGED (возникает после перемещения), или

3. WM_MOVE (возникает после перемещения)

Можно ли сделать так – одновременно иметь на экране всегда доступную форму – например, «Навигатор», и, открывая модальные формы, иметь всегда доступ к форме «Навигатор»?

Обманом можно все.

И вот это привесь на OnShow почти модальной формы

Как создать окна непрямоугольной формы и работать с ними?

Достаточно создать регион нужной формы и вызвать SetWindowRgn —

HRGN rgn := CreateEllipticRgn(10,10,100,100);

SetWindowRgn(hMyWnd,rgn); // Вот и будет круглое окно

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

Попробуйте вот этот обpаботчик OnCreate : На меня это произвело впечатление.

Result := CreatePolygonRgn(P, 5, WINDING);

Как запретить кнопку Close [×] в заголовке окна?

Вот кусок, который делает все, что тебе нужно:

Style := GetWindowLong(Handle, GWL_STYLE);

SetWindowLong(Handle, GWL_STYLE, Style And Not WS_SYSMENU);

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

procedure TForm1.Button1Click(Sender: TObject);

Windows.EnableMenuItem(SysMenu, SC_CLOSE, MF_DISABLED or MF_GRAYED);

procedure TForm1.Button2Click(Sender: TObject);

Но это окно можно закрыть из TaskBar’а.

Мерцание формы

Как бы это осуществить рисование в окне без его дурацкого мерцания и без помощи создания виртуального изображения в памяти? WM_SETREDRAW здесь поможет?

Попробуйте этот код. Даже если некоторые компоненты имеют пару BeginUpdate / EndUpdate, то для таких компонентов, как TTreeView, интенсивное рисование может послужить причиной перемещения полосы прокрутки и появления других «барабашек». В таких ситуаций вместо дескриптора элемента управления используйте родительский дескриптор.

procedure BeginScreenUpdate(hwnd : THandle);

if (hwnd = 0) then hwnd := Application.MainForm.Handle;

procedure EndScreenUpdate(hwnd : THandle; erase : Boolean);

if (hwnd = 0) then hwnd := Application.MainForm.Handle;

RedrawWindow(hwnd, nil, 0, DW_FRAME + RDW_INVALIDATE + RDW_ALLCHILDREN + RDW_NOINTERNALPAINT);

Минимизация модального окна

Мне нужно открыть из моей формы модальное окно, т.е. приостановить работу в моей форме до обработки этого модального окна. Но при этом я теряю возможность убрать (минимизировать) мою форму

if Application.Terminated then ModalResult := mrCancel;

SendMessage(Handle, CM_DEACTIVATE, 0, 0);

Конечно, в TMyForm должно быть FormStyle := fsStayOnTop;

Прозрачная форма

Высылаю прогу которая делает прозрачной форму. Может кому-нибудь поможет в его дизайнерских изысканиях.

FullRgn := CreateRectRgn(0, 0, Width, Height);

Y := Height — ClientHeight — Margin;

ClientRgn := CreateRectRgn(X, Y, X + ClientWidth, Y + ClientHeight);


CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);

CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height);

CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);

FullRgn := CreateRectRgn(0, 0, Width, Height);

CombineRgn(FullRgn, FullRgn, FullRgn, RGN_COPY);

Каким образом можно изменить системное меню формы?

Hе знаю как насчет акселераторов,надо поискать, а вот добавить пункт меню(Item) — пожалуйста

procedure wmSysCommand(var Message:TMessage); message WM_SYSCOMMAND;

InsertMenu(SysMenu, Word(-1), MF_SEPARATOR, ID_ABOUT, »);

InsertMenu(SysMenu, Word(-1), MF_BYPOSITION, ID_Calendar, ‘Calendar’);

InsertMenu(SysMenu, Word(-1), MF_BYPOSITION, ID_Analis, ‘Analis’);

InsertMenu(SysMenu, Word(-1), MF_BYPOSITION, ID_Edit, ‘Edit’);

Как сделать MDI-приложение, в котором способны сливаться не только меню дочернего и главного окна, но и полосы инструментов?

Вариант 1. CoolBar.

procedure TMainForm.SetBands(AControls: array of TWinControl;ABreaks: array of boolean);

procedure TMsgForm.FormActivate(Sender: TObject);

Оба массива равны по длине. CoolBar.Bands[0] должен существовать всегда. на нём я размешаю «глобальные» кнопки. СoolBar[1] тоже можно сделать в DesignTime с Break:=false и придвинуть поближе с началу. При CoolBar.AutoSize:=true возможно «мигании» (при добавлении на новую строку) так что можно добавить:

procedure TMDIForm.FormActivate(Sender: TObject);

procedure TMDIForm.FormDeactivate(Sender: TObject);

Заполнение изображением MDI-формы IV

SetWindowLong(ClientHandle, GWL_EXSTYLE, WS_EX_CLIENTEDGE or GetWindowLong(ClientHandle, GWL_EXSTYLE));

SetWindowLong(ClientHandle, GWL_WNDPROC, longint(FNewClientInstance));

Result := CallWindowProc(FOldClientInstance, ClientHandle, Msg, wParam, lParam);

Предотвращение закрытия формы

Следующий текст убирает команду закрыть из системного меню и одновременно делает серой кнопку закрыть в заголовке формы:

hMenuHandle := GetSystemMenu(Handle, FALSE);

IF (hMenuHandle <> 0) THEN DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);

Немедленный TrayIcon после старта приложения

Нужно чтобы при запуске приложения сразу исчезала с экрана главная форма и появлялась TrayIcon. В Ваших «Советы по Дельфи» на данный вопрос я нашел два решения (раздел Классы/TForm) к сожалению ни одно решения на моем компьютере не работало :-(. В связи с этим было решено продолжить поиск, и решение было найдено:

На Главную форму приложения помещаем компонент (TEdit или другой любой, который может иметь фокус), затем устанавливаем свойства:

В обработчик события OnEnter записываем (этот код взял из «Советов по Дельфи»):

Button1.SetFocus; //Устанавливаем фокус на другой компонент формы (у меня был Button1 )

Edit1.Visible:=False; //Делаем добавочный компонент невидимым – т.к. он больше нам не нужен

При запуске приложения создается форма и фокус получает компонент со свойством TabOrder:=0, при получении фокуса вызывается процедура OnEnter для нашего компонента и происходит скрытие формы.

Для восстановления формы необходим код:

Для реализации TrayIcon был использован компонент TRxTrayIcon из библиотеки RxLib ver.2.75 Данное решение имеет один недостаток – незначительное мерцание формы при ее сворачивании.

Заполнение формы изображением

Почитал я тут ваши ‘Советы ……’ и решил дополнить ответ по теме создание фона на форме раздела классы\tform

Чтобы заполнить вашу форму повторяющимся изображением нужно


1. Разместить на форме image

2. Присвоить его свойству visible значение false

3. В обработчике события формы OnCreate разместить следующий код :

Хочу заметить , что при использовании этого св-ва св-ва color & style не действительны! А самое главное при изменении размеров формы ваше повторяюшееся изображение будет автоматически перересовываться и вам не понадобится обрабатывать событие paint & resize.

С уважением, Dmitry Morsin

Создание консольных приложений

Создание консольных приложений. (Об этом в советах немножко есть, но очень не конкретно)

Как уже отмечалось в совете [000092] (да и в Хелпе) в консольных приложениях в Delphi можно использовать в принципе весь дельфийский арсенал. Правда и работать они будут лишь под Windows. (Кстати этот способ можно применить для модернизации программ на Паскале под Windows).

Этот код был использован для вывода результатов работы программы проверки (неважно чего) чтобы не приходилось смотреть файл с результатами. Главная проблема была в том, что консоль (если запуск был из Windows) оставалась висеть позади формы до её закрытия. Вреда конечно никакого, но не приятно. Если же запуск из Нортона или т.п., то всё идёт нормально

Windows, Forms, Dialogs, SysUtils, StdCtrls, Controls; // и (или) т.п.

MainForm: TForm; // если нужна форма

// могут быть также любые другие визуальные компоненты

// здесь могут быть процедуры и функции, т.е всё как в обычном Паскале

FreeConsole; // Отцепиться от консоли, т.е она просто исчезнет (в случае запуска из Windows) и останется только форма

// Handle:= GetForegroundWindow; // Получить Handle консоли

// ShowWindow(Handle, SW_HIDE); // Спрятать консоль

// ShowWindow(Handle, SW_SHOW); // Показать консоль

// здесь могут быть и другие компоненты

with CreateMessageDialog(‘Текст сообщения’, mtInformation, [mbOk]) do try

// это для второго пути, иначе она так и останется висеть свёрнутой

// ShowWindow(Handle, SW_SHOW); // Показать консоль

События приложения

…проблема в том, что когда приложение Delphi минимизировано, десктиптор окна в этом случае совершенно другой. Объект Application в действительности дескриптор собственного окна! Application.Handle является окном, которое активно при минимизированном приложении. Когда вы минимизируете ваше приложение, все формы просто прячутся (hidden). Обратите внимание на методы Application Minimize и Restore. Также обратите внимание, что у TApplication есть два недокументированных события, OnMinimize и OnRestore. Они принадлежат приложению, поскольку в TForm нет обработчиков событий, возникающих при минимизации главного окна. Немного странно. Я думаю так сделано для поддержки SDI-приложений.

Нужны ли мне формы в сервере приложений?

Необязательно, чтобы они были видимы, но должна присутствовать хотя бы одна. Чтобы сделать главную форму невидимой, установите

в файле проекта.

Создание формы на основе строки

В данном документе рассказывается о том, как в Delрhi можно создать экземпляр формы на основе строки, содержащей имя типа. Код примера прилагается.

На кого расчитан данный документ?

На любого программиста, имеющего начальные знания для работы с Delphi. Имеет отношение к любой версии Delphi.

Создание формы на основе строки

Чтобы можно было создать экземпляр формы на основе строки, содержащей имя типа, вы должны в первую очередь зарегистрировать данный тип в Delphi. Это выполняется функцией «RegisterClass». RegisterClass описан следующим образом:

procedure RegisterClass(AClass: TPersistentClass);

AClass – класс TPersistent. Другими словами, класс, который вы хотите регистрировать, в какой-то точке должен наследоваться от TPersistent. Поскольку все элементы управления Delphi, включая формы, соблюдают это требование, то проблем быть не должно. Но такой способ не пройдет, если регистрируемые классы наследуются непосредственно от TObject.

После регистрации класса, вы можете найти указатель на тип, передавая строку в FindClass. Функция возвратит ссылку на класс, которую можно использовать для создания формы. Небольшой поясняющий пример:

procedure TForm1.Button2Click(Sender: TObject);

Данный код создаст тип TForm2, который мы зарегистрировали с помощью RegisterClass.

Создайте новый проект, затем добавьте 4 формы так, чтобы в общей сложности получилось 5. В реальном проекте вы можете заполнить их необходимыми элементами управления, для данного же примера это не важно.

В первой форме разместите поле редактирования и кнопку. Удалите все формы, кроме главной, из списка AutoCreate. Наконец, скопируйте приведенный ниже код в unit1, он позволит вам создавать форму по имени типа класса, введенному в поле редактирования.


uses Unit2, Unit3, Unit4, Unit5, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

procedure TForm1.Button1Click(Sender: TObject);

Показ логотипа при запуске приложения III

Своим опытом делится Nomadic :

A: Смотрите пример в X:\DELPHI\DEMOS\DB\MASTAPP\mastapp.dpr.

Удобно использовать функцию ShowSplashWindow из rxLib.

Показ логотипа при запуске приложения IV

Как добавить логотип к вашему приложению

Логотип (заставка) является важной составляющей вашего приложения. Он позволяет занять время во время загрузки и сообщить пользователю дополнительные сведения о программе. Логотип сделает ваше приложение более профессиональным.

Кроме того, заставка позволяет не только отличить ваше приложение от другого, но и отличить одну версию приложения от другой.

Илон Маск рекомендует:  Что такое код ldexp

Имеется множество типов заставок (Splash Screen). Самый распространный тип — показ логотипа во время загрузки приложения. Обычно такие экраны отображают имя приложения, автора, версию, авторские права и изображение или иконку, идентифицирующую приложение.

Также, некоторые приложения используют этот экран для показа линейки прогресса при выполнении длительного процесса. Примером такого типа экрана может быть диалог с выводом числа процентов выполненного запроса к базе данных, файловая задача, или задача обработки чисел. При длительных процессах наличие такого диалога означает вежливость программы по отношению к пользователю.

Надеюсь, вы оценили преимущества заставок. Давайте теперь попробуем создать простую заставку своими руками.

1. Добавьте форму в ваш проект File | New Form.. Комментарий: Заставка (Splash Screen) похожа на любую другую форму.

2. Измените свойство формы Name на SplashScreen

3. Измените свойство формы BorderStyle на bsNone

4. Измените свойство формы Position на poScreenCenter

5. Сделайте заставку привлекательной и функциональной путем добавления на нее необходимых компонентов и изображений. (компоненты Label, Panel, Image, Shape и Bevel)

6. Отредактируйте свойства добавленных компонентов

7. Выберите в меню Delphi IDE Options | Project

8. Уберите SplashScreen-форму из списка Auto-create-списка (списка автоматически создаваемых форм)

Комментарий: Вы динамически создаете экземпляр заставки

9. Добавьте модуль, содержащий TSplashScreen, в список используемых модулей главной формы вашего приложения. Пример:

uses SysUtils, WinTypes, WinProcs, Messages, Classes,Graphics, Controls, Forms, Dialogs, StdCtrls, unit2; ERROR_SUCCESS then raise ERegistryException.CreateResFmt(@SRegSetDataFailed, [name]);

// Чтение TStringList ввиде значения типа REG_MULTI_SZ из реестра

Как настроить системное меню формы Windows?

Я хочу добавить к моему приложению старый возраст. Я хочу добавить его в «системное меню» приложения (тот, который появляется, когда мы нажимаем значок приложения в верхнем левом углу). Итак, как я могу это сделать в .NET?

Windows упрощает получение дескриптора копии системного меню формы для целей настройки с помощью функции GetSystemMenu . Жесткая часть заключается в том, что вы сами можете выполнить соответствующие изменения в возвращаемом меню, используя такие функции, как AppendMenu , InsertMenu и DeleteMenu так же, как если бы вы вы программировали непосредственно против Win32 API.

Однако, если все, что вы хотите сделать, это добавить простой пункт меню, это действительно не так уж сложно. Например, вам нужно будет использовать только функцию AppendMenu , потому что все, что вы хотите сделать, это добавить элемент или два в конец меню. Выполнение чего-либо более продвинутого (например, вставка элемента в середине меню, отображение растрового изображения в элементе меню, отображение элементов меню, установка элемента меню по умолчанию и т.д.) Требует немного больше работы. Но как только вы знаете, как это сделать, вы можете пойти на дикую природу. документация по функциям, связанным с меню сообщает все.

Здесь полный код формы, который добавляет строку разделителя и элемент «О» в нижней части его системного меню (также называемое меню окна):

И вот как выглядит готовый продукт:

Значение-добавление довольно мало для количества пинвы, которое вам понадобится. Но это возможно. Используйте GetSystemMenu() для извлечения дескриптора системного меню. Затем InsertMenuItem добавит запись. Вы должны сделать это в переопределении OnHandleCreated(), чтобы воссоздать меню, когда окно будет воссоздано.

Как изменить меню правой кнопки. Очистка Контекстного меню Windows

Контекстное меню (меню правой кнопки мыши)– удобный инструмент для ускорения работы в Windows. Сегодня мы раскроем несколько простых секретов работы с контекстным меню и системным реестром. Читайте, как без посторонних приложений настроить этот важный элемент под свои потребности, используя лишь встроенный редактор реестра regedit.

Чем удобно контекстное меню (меню правой кнопки) и зачем его очищать

Хочется сразу определиться с терминологией, чтобы в дальнейшем не возникало путаницы.

Контекстное меню Проводника или, как его иногда называют, меню действия – это набор команд, вызываемый при помощи щелчка правой (контекстной) кнопки мыши на любом файле или папке. В зависимости от объекта, для которого оно вызывается, меню будет иметь разный вид или «контекст».

Примечание. Конечно, меню действий есть не только у Проводника Windows, а и у большинства установленных приложений, ведь это удобнейший способ доступа к самым важным командам.

Сразу после установки операционной системы, контекстное меню имеет стандартный и опрятный вид, но по мере установки дополнительного софта, в него постоянно добавляются новые пункты. В конце концов, их становится настолько много, что использование этого полезного инструмента превращается в муку. Поэтому критически важно уметь поддерживать в порядке содержимое контекстного меню Windows для быстрой и комфортной работы.


Это можно делать двумя способами:

  • В полуавтоматическом режиме, используя стороннее программное обеспечение.
  • Вручную, при помощи редактора реестра Windows.

Возможно, первый способ может быть немного легче, но вторым способом нет необходимости использовать различные сомнительные программы скачанные с интернета, все делается стандартными средствами.

Тем более, использование реестра позволит глубже вникнуть во внутренние процессы системы и узнать много нового, так что мы расскажем именно о втором варианте действий.

Как отредактировать контекстное меню Проводника через реестр

Запускаем редактор реестра:

  1. Входим в меню П уск.
  2. Вводим в строку поиска команду regedit и жмем Enter .

Важно! Любые неосторожные и необдуманные операции могут иметь опасные последствия, вплоть до полного отказа загрузки Windows. Чтобы подстраховать себя от ошибок, обязательно сделайте резервную копию реестра перед началом его редактирования!

Порядок действий при создании резервного файла реестра:

  1. Заходим в меню «Файл» в отрытом редакторе.
  2. Выбираем пункт «Экспорт».
  3. В открывшемся окне, в нижнем поле «Диапазон экспорта», выбираем «Весь реестр».
  4. Указываем нужное место расположения и имя нового файла и жмем «Сохранить».

Примечание. В случае возникновения проблем после ручного редактирования, реестр можно будет восстановить до его первоначального состояние из резервной копии, используя пункт «Импорт» в меню «Файл» редактора regedit.

Как видим, сам реестр имеет оригинальную древовидную структуру. В левой части редактора отображается само дерево, а в правой – список параметров в выбранной ветке. Для работы с контекстным меню нас интересует один-единственный раздел: «HKEY_CLASSES_ROOT».

Как уже упоминалось, разным объектам (папкам, файлам) соответствуют разные наборы команд, поэтому редактировать в реестре их придется по отдельности. Наши основные цели: очистка контекстного меню папок и общих пунктов меню для всех типов файлов.

Важно! Стандартные системные пункты контекстного меню через реестр изменять не будем. Редактируются только элементы, добавленные установленными приложениями.

Очистка контекстного меню папок

Все настройки контекстного меню директорий хранятся в ветках:

… Directory Shellex ContextMenuHandlers .

… Folder Shell e x ContextMenuHandlers .

Если присмотреться, то среди разветвлений указанных веток легко увидеть знакомые команды. Так, ответвление реестра « Directory Shell » содержит в себе пункты верхней части меню, а « Directory Shellex ContextMenuHandlers » – нижней. « Folder ShellEx ContextMenuHandlers », в основном, повторяет содержание предыдущей ветки, так что одинаковые пункты при необходимости удаляйте из обеих веток.

Осталось только удалить лишние команды. Выбор, что убрать, а что оставить в списке – это уже личное дело каждого. Тем более, что в зависимости от списка установленных приложений, содержание меню будет существенно отличаться. Нажмите правой кнопкой мышки на не нужную запись в реестре и выберите «Удалить». Затем повторите эту операцию для остальных выбранных элементов.

Вот такой аккуратный вид имеют рассматриваемые ветки реестра и само меню после завершения процедуры очистки.

Очистка контекстного меню файлов

Сама процедура ничем не отличается от той, которая проводилась в предыдущем разделе. Изменились только ответвления ветки реестра «HKEY_CLASSES_ROOT», хранящие необходимые параметры.

В них хранятся общие элементы для всех зарегистрированных в системе типов файлов.

По примеру очистки для папок, удаляем все ненужные ветки в реестре и получаем красивое и удобное контекстное меню.

Faq каким образом можно изменить системное меню формы?

В этом примере используется функция InsertMenu, так как нам надо просто добавить пункты в меню. Если планируется использование дополнительных спецэффектов, то эту функцию можно заменить на более современную InsertMenuItem.

Но просто добавлять пункты в меню бессмысленно, нам надо как-то обрабатывать события, возникающие при их выборе. Это тоже несложно. При выборе пункта системного меню родительскому окну отправляется сообщение WM_SYSCOMMAND, у которого wParam имеет значение заданного идентификатора этого пункта.

  1. ; Обработчик сообщений окна
  2. . . .
  3. cmp [ msg ] , WM_SYSCOMMAND
  4. je . wmmenu
  5. . . .
  6. ; Обработчик сообщений от системного меню
  7. . wmmenu :
  8. ; Выбран первый добавленный пункт меню?
  9. cmp [ wparam ] , >je . action_1
  10. ; Выбран второй добавленный пункт меню?
  11. cmp [ wparam ] , >je . action_2
  12. ; Передача системного сообщения дальше по цепочке обработчиков
  13. invoke DefWindowProc , [ hwnddlg ] , [ msg ] , [ wparam ] , [ lparam ]
  14. jmp . processed
  15. . . .

Обратите внимание, что в обработчик сообщения добавлена функция DefWindowProc. Она нужна, чтобы все остальные системные сообщения, которые не относятся к системному меню, достигали своей цели. Если ее опустить, то окно вообще перестанет реагировать на внешние события: его нельзя будет закрыть нажатием на «крестик», переместить за заголовок, изменить размер и т.д.

В приложении пример программы с исходным текстом, демонстрирующий добавление своих пунктов в системное меню окна.

Пример программы с исходным текстом (FASM)

Системное меню

В разобранным нами в предыдущем подразделе кнопкам управления окна соответствует так называемое системное меню, которое вызывается щелчком в левом верхнем углу окна (обычно там имеется маленький значок, который представляет собой уменьшенную копню полного значка данного окна, хотя в некоторых случаях никакого значка может и не быть). Клавиатурная комбинация, которая вызывает это меню, — + . Такое меню имеется у любого окна, которое вообще имеет заголовок. Кроме самых простых диалоговых окон. У некоторых окон в Windows Vista/7 (в том числе у окна Компьютер) специальный значок системного меню отсутствует, но в любом случае его можно также вызывать щелчком правой кнопки мыши на заголовке окна. Рассмотрев это меню внимательно (рис. 1.15). вы увидите, что в нем полностью дублированы не только функции экранных кнопок, но и другие возможные манипу ляции с окном, даже такие, как изменение его размеров. На его примере мы разберем, как обращаться с меню вообще.

Самый первый пункт. Восстановить (Restore), обозначен тусклым серым цветом, и при нажатии на нем ничего не происходит— этот пу нкт в данный момент недоступен. Почему ? Потому что пункт Восстановить относится к ситуации, когда окно свернуто на панель задач или, наоборот, развернуто во весь экран, а в данном случае он ничего не сделает В подобных случаях пункты меню и делаются недоступными. Полу чить доступ к этому меню, если окно свернуто на панель задач, естественно. можно только комбинацией клавиш + или щелчком правой кнопкой мыши на заголовке нужного окна.

При управлении компьютером с клавиатуры клавиша — вообще одна из самых употребляемых, потому что предназначена для отмены предыдущего действия (от англ. escape— выход, переход). Не все. разумеется, действия с ее помощью можно отменить — для этого есть и другие способы, но у нее есть одно поистине бесценное качество: нажатием этой клавиши практически невозможно что-то испортить и нажимать ее можно без особой боязни.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL