Основным недостатком использования .mm
по сравнению с .m
для «нормального» Objective-C является то, что время компиляции значительно выше для Objective-C ++. Это потому, что компилятор C ++ занимает больше времени, чем компилятор C. С Xcode 3.2 и выше код Objective-C может использовать цепочку инструментов внешнего интерфейса Clang , чтобы значительно ускорить время компиляции Objective-C / C. Поскольку Clang еще не поддерживает Objective-C ++ / C ++, это еще больше увеличивает разрыв во времени компиляции между ними.
Лучшая стратегия - использовать .m
по умолчанию. Если вам понадобится использовать Objective-C ++ на более поздних этапах разработки, нет ничего плохого в том, чтобы переименовать файл для использования расширения .mm
. Если это так изнутри XCode, проект будет автоматически обновлен для использования вновь названного файла.
Конечно, все стандартные предупреждения применяются, когда вы пытаетесь сравнить производительность Objective-C ++ и Objective-C во время выполнения. Поскольку Objective-C ++ является надмножеством C ++, а Objective-C - надмножеством C, вы имеете дело с двумя разными языками, каждый из которых имеет компромисс между производительностью и временем выполнения. Учитывая, что вы вообще используете Objective-X, вы, скорее всего, пишете приложение уровня пользователя (не приложение уровня системы), и разница в производительности между C и C ++, вероятно, будет полностью определяться вашими способностями кодировать эффективные алгоритмы в каждый язык. Если вы разработчик на C ++, вы, вероятно, будете писать код лучше, чем на C и наоборот. Поэтому, как всегда, используйте соответствующий инструмент для работы.
Для справки, вас также может заинтересовать этот ответ: C против C ++ (Objective-C против Objective-C ++) для iPhone
ОБНОВЛЕНИЕ 17 февраля 2012 г. Начиная с Xcode 4.0 (с LLVM 3.0), Clang поддерживает Objective-C ++. Даже поддержка C ++ 11 сейчас достаточно сильна.
Вы не упомянули, какая версия Delphi ...
В новых версиях Delphi в TCustomForm добавлены два новых свойства: PopupMode и PopupParent. Установка PopupParent вашего модального диалога на форму, создающую этот диалог, гарантирует, что дочерняя форма остается поверх своей родительской. Обычно это решает проблему, которую вы описываете.
Я думаю, что эта пара свойств была добавлена в Delphi 2006, но, возможно, это был 2005 год. Они определенно присутствуют в Delphi 2007 и новее.
РЕДАКТИРОВАТЬ: После просмотра вы используете Delphi 7, единственное, что у меня есть, это то, что в коде, который отображает вашу модальную форму, вы отключите форму, создающую ее, и снова включите ее при возврате. Это должно помешать окну создания получать ввод, что может помочь сохранить правильный Z-порядок.
Что-то вроде этого может работать (не проверено, поскольку я больше не использую D7):
procedure TForm1.ShowForm2;
begin
Self.Enabled := False;
try
with TForm2.Create(nil) do
begin
try
if ShowModal = mrOk then
// Returned OK. Do something;
finally
Free;
end;
end;
finally
Self.Enabled := True;
end;
end;
Если Form2 создает модальное окно (как вы упомянули), просто повторите процесс - отключите Form2, создайте Form3 и покажите это модально и повторно включить Form2, когда он вернется. Обязательно используйте try..inally, как я показал, чтобы, если что-то пойдет не так в модальной форме, форма создания всегда будет повторно активирована.
Я обнаружил, что использование флага «Всегда поверх» в нескольких формах вызывает проблемы с Z-порядком. И вам также может понадобиться функция BringWindowToTop
.
При запуске окна сообщения с использованием встроенного WinAPI ( MessageBox
) я обнаружил, что передача вызывающего окна дескриптор необходим для того, чтобы подсказка всегда появлялась вверху.
Из этой ссылки видно, что проблема связана с «окном фантомного просмотра», появившимся в 2000 / XP. Вы можете отключить функцию двоения, вызвав следующий код при запуске.
procedure DisableProcessWindowsGhosting;
var
DisableProcessWindowsGhostingProc: procedure;
begin
DisableProcessWindowsGhostingProc := GetProcAddress(
GetModuleHandle('user32.dll'),
'DisableProcessWindowsGhosting');
if Assigned(DisableProcessWindowsGhostingProc) then
DisableProcessWindowsGhostingProc;
end;
Единственная проблема, которую я вижу, это то, что это вызовет проблемы с функцией, которая позволяет пользователю минимизировать, переместить или закрыть основной окно приложения, которое не отвечает . Но таким образом вам не нужно покрывать каждый вызов кодом Self.Enabled: = False
.
Извините за добавление отдельного ответа, но я провел немного больше исследований, и некоторые из них показывают, что мой предыдущий ответ (DisableProcessWindowsGhosting) не помогает. Поскольку я не всегда могу воспроизвести эту проблему, я не могу сказать наверняка.
Я нашел подходящее решение. Я сослался на код в Delphi 2007 для метода CreateParams, и он довольно близко соответствует (без всего остального кода, который обрабатывает PopupMode).
Я создал модуль, ниже которого подклассы TForm
.
unit uModalForms;
interface
uses Forms, Controls, Windows;
type
TModalForm = class(TForm)
protected
procedure CreateParams(var params: TCreateParams); override;
end;
implementation
procedure TModalForm.CreateParams(var params: TCreateParams);
begin
inherited;
params.WndParent := Screen.ActiveForm.Handle;
if (params.WndParent <> 0) and (IsIconic(params.WndParent)
or not IsWindowVisible(params.WndParent)
or not IsWindowEnabled(params.WndParent)) then
params.WndParent := 0;
if params.WndParent = 0 then
params.WndParent := Application.Handle;
end;
Затем я включаю этот модуль в модуль формы, а затем меняю класс формы (в файле кода .pas) с class (TForm)
на класс (TModalForm)
У меня это работает, похоже, близко к решению CodeGear.