Общие вопросы
BEEP , для дельфи , который работает, как в B.Pascal 7.0
Я применяю следующий код, однако он работает только под Win9x/me
(Под WinNT/2000/XP вы можете использовать Beep(Tone, Duration)
- задавать тон и продолжительность звучания).
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Навороченные формы с огромным количеством визуальных компонентов, помноженные на количество этих форм, могут вызвать ряд серьезных проблем при разработке и использовании программы.
Приложение надолго подвисает при загрузке. Время уходит на инициализацию большого количества форм, стоящих в AutoCreate.
Наблюдаются многочисленные глюки при прорисовке, сообщения системы об ошибках и перерасходе ресурсов без видимых причин, вплоть до убиения приложения системой или краха системы. Характерно для Windows линии 9X, у которых максимальное количество графических и оконных ресурсов (GDI и USER) сильно ограничено.
Зачастую, чтобы не расставлять и настраивать множество однообразных контролов на форме вручную, программист пишет код для их программной инициализации и вставки, не учитывая при этом нюансы, о которых он не подозревал при визуальной разработке. В результате он может получить утечку памяти и прочих ресурсов, если форма создается/уничтожается динамически многократно в процессе работы.
Пользователь теряется в перегруженном интерфейсе программы, будучи не в состоянии использовать все его возможности и затрудняясь в выполнении простых задач.
ТИПОВЫЕ РЕШЕНИЯ.
1. | Уменьшить количество автоматически создаваемых форм. Создавать тяжелые формы в тот момент, когда они понадобятся, и уничтожать при закрытии. При этом нужно следить за своевременной очисткой и проверкой глобальных ссылок на формы. |
2. | У динамически создаваемых компонентов устанавливать владельца и родителя. Подробности - в статье "Жизнь и смерть в режиме run-time". |
3. | Большое количество форм не всегда оправдано. Если пользователь не получает дополнительных удобств от того, что может открыть много форм (часто он не может их увидеть одновременно или работает постоянно с одной), то это неверное архитектурное решение. |
Интерфейс MDI - хорошая концепция. Но всякое техническое решение имеет свою область применения. Это удобно, когда пользователю нужно работать с однотипными объектами в разных окнах и переходить от одного к другому, причем количество их заранее неизвестно, и допускается изменение размеров окна. Примеры - работа с документами (Word, Excel, etc.). |
4. | Как правило, многочисленные элементы управления не нужны пользователю одновременно (вспомните о правиле 7±2 - именно таково среднее количество объектов, за которыми человек может следить одновременно, не напрягаясь). Их можно разделить на группы и расположить на страницах компонента TPageControl. Таким способом можно скрыть видимую сложность очень большого интерфейса по вводу и редактированию данных. |
Если группы компонентов однотипны (меняются только данные), то решение еще более упрощается, с одновременным снятием нагрузки на ресурсы системы. Компонент TTabControl, который внешне выглядит также, как и TPageControl, содержит только одну группу контролов, а программист по событию смены закладки OnChange имеет возможность сменить данные. |
5. | Большое количество регулярно расположенных контролов TEdit, TLabel успешно заменяется на TStringGrid, специально для этого предназначенный. Кроме всего прочего, он имеет удобную прокрутку, размеры таблицы не будут ограничены размерами формы. |
В случае, если нужно много TComboBox, применяют следующую хитрость. Для визуализации используют TStringGrid, а для редактирования в текущую ячейку вставляют TComboBox, устанавливая ему размеры и координаты по ячейке и набивая его программно (если набор элементов меняется). Один и тот же экземпляр редактирующего контрола используется во всех ячейках, поскольку он не нужен одновременно везде. Эта же техника используется и в VCL для редактирования ячеек TStringGrid, TDBGrid. |
Есть масса компонентов типа TStringGrid сторонних разработчиков, которые расширяют возможности стандартного. |
6. | DB-aware визуальные компоненты - такие как TDBGrid - способны обрабатывать огромный объем данных, не требуя при этом пропорциональное количество ресурсов GDI/USER. В конце концов, если не хочется связываться с СУБД, можно загнать информацию в TClientDataSet и кормить из него DB-aware controls на форме. Одновременно получаешь все прелести сортировки и фильтрации данных. |
В случае сложного набора контролов для каждой записи, при необходимости видеть несколько таких групп одновременно, хорошо подходит компонент TDBCtrlGrid. |
7. | Следует стремиться уменьшить количество компонентов - потомков TWinControl (например - TButton), заменяя их на потомки TGraphicControl (пример - TSpeedButton). Последние не используют объекты USER, поскольку не являются окнами в понятиях Windows. |
8. | Рекомендуется разрабатывать и эксплуатировать ресурсоемкие приложения в среде Windows NT и ее наследников (2000, XP). |
Автор:Александр Малыгин
Взято с https://delphiworld.narod
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
В Delphi 7 в модуле StrUtils внесены некоторые изменения.
Есть новая функция: PosEx.
Обьявление этих функций:
Code: |
Function Pos(Substr: String; S: String): Integer; Function PosEx(Const SubStr, S: String; Offset: Cardinal = 1): Integer; |
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Code: |
var X1, X2: Byte; begin X1 := X2 xor X2; X2 := X1 xor X2; // X2 = X1 X1 := X1 xor X2; // X1 = X2 |
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Paramcount - показывает сколько параметров передано
Paramstr(0) - это имя с путем твоей программы
Paramstr(1) - имя первого параметра
Paramstr(2) - имя второго параметра и т.д.
Если ты запускаешь:
с:\myprog.exe /a -b22 c:\dev
то Paramcount будет равен 3
Paramstr(0) будет равен с:\myprog.exe
Paramstr(1) будет равен /a
Paramstr(2) будет равен -b22
Paramstr(3) будет равен c:\dev
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Code: |
unit MsFormR;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; Memo1: TMemo; ListBox1: TListBox; Panel1: TPanel; Button1: TButton; Button2: TButton; Splitter1: TSplitter; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private MemStr1: TMemoryStream; public procedure ShowMemStr; end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject); begin MemStr1 := TMemoryStream.Create; end;
procedure TForm1.Button1Click(Sender: TObject); var Str1: TFileStream; begin OpenDialog1.Filter := 'Any file (*.*)|*.*'; OpenDialog1.DefaultExt := '*'; if OpenDialog1.Execute then begin Str1 := TFileStream.Create ( OpenDialog1.Filename, fmOpenRead); try MemStr1.LoadFromStream (Str1); ShowMemStr; Button2.Enabled := true; finally Str1.Free; end; end; end;
procedure TForm1.ShowMemStr; begin Memo1.Lines.LoadFromStream (MemStr1); end;
procedure TForm1.Button2Click(Sender: TObject); const ndx: LongInt = 1; var pch: PChar; tmpC: Char; begin pch := MemStr1.Memory; tmpC := pch[ndx]; pch[ndx] := #0; ListBox1.Items.SetText(MemStr1.Memory); pch[ndx] := tmpC;
if ndx < MemStr1.Size then Inc(ndx) else Button2.Enabled := False; end;
end. |
Взято с https://delphiworld.narod
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Каким образом можно использовать переменную типа String в качестве имени процедуры?
Если все процедуры, которые вы собираетесь вызывать, имеют список с одними и теми же параметрами (или все без параметров), то это не трудно. Для этого необходимы: процедурный тип, соответствующий вашей процедуре, например:
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Есть такой способ вызова функций по имени, если они совпадают по сигнатуре:
Code: |
{©Drkb v.3(2007): www.drkb.ru} function TestFunc1(d: Double): Integer; begin .... end;
function TestFunc2(d: Double): Integer; begin .... end;
exports TestFunc1, TestFunc2;
procedure TForm1.Button1Click(Sender: TObject); var Func: function (d: Double): Integer; begin @Func := GetProcAddress(hInstance, PChar(Edit1.Text)); if @Func = nilthen raise Exception.CreateFmt('Функция с именем "%s" не существует', [Edit1.Text]); ShowMessage(IntToStr(Func(10.63))); end; |
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Передача параметров процедуры и функции в дельфи:
Code: |
Type Ta=arrayof something; Var a:Ta; |
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Может кто объяснит подробнее особенности применения директив вызовов процедур: register, pascal, cdecl, stdcall, safecall.
В чём отличия, когда и какие надо применять, какие преимущества и недостатки?
Разница в способе передачи параметров в функцию и возврата параметров из функции.
stdcall - юзается (вроде) а винапях. Передача аргументов справа налево. Стек очищает вызываемая процедура. Возвращает разультат в EAX (помойму)
pascal - юзалось в вин16апи. Передача в аргументов слева направо. Стек очищает вызываемая. В паскале результат возвращался в al, ax или в dx:ax. Как в Дельфи - не помню, вероятно а EAX.
register - передача всего через регистры процессора. Как именно - зависит от компилятора.
cdecl - не помню. Вроде тоже, что и stdcall, только стек чистит вызывающая процедура
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Code: |
{ You maybe have to access just a part of a GUID. }
{ Const for the function Format(...) } const fsGUID: string = 'D1: $%s'#13#10'D2: $%s'#13#10'D3: $%s'#13#10 + 'D4: $%s $%s $%s $%s $%s $%s $%s $%s'; fsGUIDParts: string = 'D%d:%s';
// Type for the GUID part to be shown type
TGUIDPART = (guidp_NoFormat, guidp_All, guidp_D1, guidp_D2, guidp_D3, guidp_D4);
{ This GUIDToStringEx function give you the full GUID string according with then format string FStr (you can change it !!!) } function GUIDToStringEx(Guid: TGuid; FStr: string): string; overload; begin Result := Format(FStr, [IntToHex(GUID.D1, 8), IntToHex(GUID.D2, 4), IntToHex(GUID.D3, 4), IntToHex(GUID.D4[0], 2), IntToHex(GUID.D4[1], 2), IntToHex(GUID.D4[2], 2), IntToHex(GUID.D4[3], 2), IntToHex(GUID.D4[4], 2), IntToHex(GUID.D4[5], 2), IntToHex(GUID.D4[6], 2), IntToHex(GUID.D4[7], 2) ]); end;
{ This GUIDToStringEx function give you the part of the GUID to be shown, according to the part type GUIDPart } function GUIDToStringEx(Guid: TGuid; Part: TGUIDPART): string; overload; var i: Integer; S: string; begin S := ''; case Part of guidp_NoFormat: S := GUIDToString(Guid); guidp_All: S := GUIDToStringEx(Guid, fsGUID); guidp_D1: S := Format(fsGUIDParts, [1, ' $' + IntToHex(GUID.D1, 8)]); guidp_D2: S := Format(fsGUIDParts, [2, ' $' + IntToHex(GUID.D2, 4)]); guidp_D3: S := Format(fsGUIDParts, [3, ' $' + IntToHex(GUID.D3, 4)]); guidp_D4: begin for i := 0to7do S := S + ' $' + IntToHex(GUID.D4[i], 2); S := Format(fsGUIDParts, [4, S]); end; else S := '?'; end; Result := S; end;
{ How to use the different GUIDToStringEx functions }
procedure TForm1.Button1Click(Sender: TObject); var NewGUID: TGUID; begin { Create a new GUID } NewGUID := StringToGUID(CreateClassID);
{ Standard formated GUID string } label1.Caption := GUIDToStringEx(NewGUID, guidp_NoFormat) + #13#10 +
{ Full formated GUID string acc. with fsGUID} GUIDToStringEx(NewGUID, fsGUID) + #13#10 +
{ Full formated GUID string with default formating} GUIDToStringEx(NewGUID, guidp_All) + #13#10 +
{ Part D3 of the GUID only } GUIDToStringEx(NewGUID, guidp_D3); end; |
Взято с сайтаhttps://www.swissdelphicenter.ch/en/tipsindex
- Подробности
- Родительская категория: Язык программирования Дельфи
- Категория: Общие вопросы
Страница 1 из 2