Полезные советы
(взято с Ruslan Delphi Page)
Просмотр удаленных записей в DBase
Прозрачный растр
Как убрать приложение с taskbar
Отключение CTRL-ALT-DEL
Колонки в TListBox
Использование OwnerDraw
Перемещение формы при нажатии на клиентскую область
Упаковка таблицы Paradox
Отправка сообщений компонентам
Ускорение работы Memo
При удалении записей в таблицах dBASE на самом деле происходит пометка записи на удаление, в то время как сами записи остаются в файле, пока таблица не будет упакована. Поэтому "удаленные" записи можно просмотреть, и даже восстановить их.
Чтобы показать помеченные на удаление записи, нужно использовать функцию BDE DbiSetProp. Ниже приведен пример функции-оболочки для DbiSetProp. Ей передается в качестве параметра таблица и логическая переменная, означающая показывать удаленные записи, или нет. Таблица может быть открыта или закрыта.
procedure TForm1.ShowDeleted(Table: TTable; ShowDeleted: Boolean); var rslt: DBIResult; szErrMsg: DBIMSG; begin Table.DisableControls; try Check(DbiSetProp(hDBIObj(Table.Handle), curSOFTDELETEON, LongInt(ShowDeleted))); finally Table.EnableControls; end; Table.Refresh; end;
Пожалуй, это самый простой способ создания прозрачного изображения. Суть его в том, что маска создается автоматически во время выполнения программы, используя значение прозрачного цвета.
MaskBitmap := TBitmap.Create; MaskBitmap.Assign(SrcBitmap ); MaskBitmap.Mask(FColor); //прозрачный цвет BitBlt(DestBitmap.Canvas.Handle, x, y, SrcBitmap.Width, SrcBitmap.Height, MaskBitmap.Canvas.Handle, 0, 0, SRCAND); BitBlt(DestBitmap.Canvas.Handle, x,y, SrcBitmap.Width, SrcBitmap.Height, SrcBitmap.Canvas.Handle, 0, 0, SRCINVERT); MaskBitmap.Free;
Между прочим, в Delphi 3 предусмотрено отображение прозрачных растров, например в объекте TPicture. Также как и в описанном методе, возможно непосредственно задавать прозрачный цвет, а также определять его автоматически.
Как спрятать приложение с панели задач Windows 95 - часто задаваемый вопрос. На него существует множество ответов. Вот самый простой вариант его решения:
ShowWindow(application.handle, sw_hide);
Бывают ситуации, когда вашей программе понадобится отключить реакцию на клавиши Ctrl-Alt-Del (например, если вы не хотите, чтобы ее выгрузили из памяти). Это можно сделать при помощи функции API SystemParametersInfo, которая позволяет узнать, либо установить параметры операционной системы, такие как установки клавиатуры, дисплея, звука и т.д. Она используется в Панели Управления. Синтакс функции следующий:
BOOL SystemParametersInfo( UINT uiAction, // параметр, который нужно узнать или установить UINT uiParam, // зависит от действия PVOID pvParam, // зависит от действия UINT fWinIni // флаг обновления информации о пользователе (user profile) );
Значение каждого параметра объясняется в Win32 Developer's Reference. Теперь, чтобы сделать то, что мы хотим, вызываем следующую прцедуру:
procedure DisableCtrlAltDel; var i : integer; begin i := 0; SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @i, 0); end.
Аналогично можно отключить Alt-Tab. Для этого нужно задать SPI_SETFASTTASKSWITCH в качестве первого параметра функции.
В книгах и других источниках по Delphi часто приводится пример создания компонента, способного выводить текст в списке в несколько колонок. Между тем, мало кому известен факт, что стандартный компонент TListBox уже содержит свойство, которое позволяет это делать. Это свойство TabWidth (в Delphi 2 оно не описано в файлах помощи, хотя так же присутствует), которое наследуется от класса TCustomListBox и задает величину табуляции в пикселах. Установите его равным, скажем, половине ширины компонента ListBox, чтобы отображалось две колонки. Когда будете добавлять строки, всавьте в нужных местах символ табуляции (^I):
ListBox1.Items.Add('Колонка1'^I'Колонка2');
Недостаток такого подхода заключается в том, что ширина колонки не изменяется авоматически в зависимости от ширины выводимых строк, что, впрочем, легко исправить. Посмотрите на метод TextWidth класса TCanvas. Он возвращает ширину в пикселах передаваемой ему в качестве параметра строки. Тогда перед добавлением каждого нового элемента в список проверяем, превышает ли его ширина ширину колонки:
with ListBox do begin W := Canvas.TextWidth(Str); if W > TabWidth then TabWidth := W; end;
Если у вас когда-нибудь возникало желание поместить изображение в списке, здесь описано, как это сделать. Данная техника может также применяться для других визуальных компонентов, которые поддерживают "прорисовку владельцем", что задается в свойсте Style. Прорисовка владельцем означает, что вместо стандартной прорисовки Windows для визуального компонента используется подпрограмма его владельца, обычно формы. Используя OwnerDraw, можно, например, изменить цвет отдельных ячеек в сетке (Grid), поместить рисунок в ComboBox, ListBox, TabSet и других компонентов, которые содержат список.
Чтобы использовать OwnerDraw, нужно, во-первых, задать свойство Style соответствующего компонента, во-вторых - добавить графический объект в список, и в-третьих - написать процедуру для прорисовки элементов списка.
В зависимости от того, различается ли размер изображения для каждого элемента списка, или нет, в свойстве Style задается значение OwnerDrawVarible или OwnerDrawFixed соответственно (точное значение зависит от компонента; для ListBox это lbOwnerDrawVarible и lbOwnerDrawFixed). Для простоты установим свойство равным lbOwnerDrawFixed.
Теперь мы должны загрузить растр, который будет отображаться в списке. Поместите компонент TImage на форму и загрузите в него нужную картинку. Эту картинку нужно будет ассоциировать со строками списка. Если только вы не собираетесь изменять способ прорисовки во время работы программы, то удобнее всего это сделать в обработчике события OnCreate формы-владельца компонента. Ниже показан пример обработчика события OnCreate, в котором происходит ассоциирование изображения со строками ListBox.
procedure TFMForm.FormCreate(Sender: TObject); const StrArray : array [0..3] of string = ('Строка 1', 'Строка 2', 'Строка 3', 'Строка 4'); var Index: Integer; begin for Index := 0 to 3 do { добавляем строки из массива } lbListBox.Items.AddObject(StrArray[Index], Image.Picture.Graphic); end;
В данном обработчике в список lbListBox добавляются строки, предварительно записанные в виде массива. Конечно, можно использовать любой другой способ хранения строк, например в виде ресурса.
Теперь мы должны написать процедуру для прорисовки элементов списка, так как после установки свойства Style Windows больше не делает это за нас. Эта процедура должна вызываться в ответ на событие OnDrawItem компонента lbListBox. Ниже приведен пример процедуры.
procedure TfmForm.lbListBoxDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var Bitmap: TBitmap; Offset: Integer; begin with (Control as TListBox).Canvas do begin FillRect(Rect); Offset := 2; Bitmap := TBitmap((Control as TListBox).Items.Objects[Index]); if Bitmap <> nil then begin BrushCopy(Bounds(Rect.Left + 2, Rect.Top, Bitmap.Width, Bitmap.Height), Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height), clRed); Offset := Bitmap.width + 6; end; TextOut(Rect.Left + Offset, Rect.Top, (Control as TListBox).Items[Index]) end; end;
Данный метод описан в технической информации (TI) Borland и бывает полезен если ваша форма не имеет области заголовка (синей полосы вверху). У такой формы свойство BorderStyle установлено равным bsNone.
Самый просотой способ заключается в том, чтобы заставить Windows думать, что произошло нажатие в области заголовка окна, когда происходит нажатие в клиентской области. Это можно сделать, добавив собственный обработчик события wm_NCHitTest. Откройте модуль вашей формы и добавьте следующее описание в разделе private:
procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest;
Процедура названа так в соответствии с соглашениями об именах в Windows, но вы можете изменить название, если вам захочется.
Теперь в разделе implementation опишем код процедуры.
procedure TForm1.WMNCHitTest(var M: TWMNCHitTest); begin inherited; //вызываем стандартный обработчик if M.Result = htClient then M.Result := htCaption; end;
Обратите внимание, что в начале вызывается стандартный обработчик.
Кроме перемещения формы, добавьте возможность завершения программы в виде кнопки или пункта меню, так как пользователь не сможет закрыть ее при помощи заголовка окна или системного меню.
Используйте следующий код для упаковки таблиц Paradox в вашей программе:
function PackParadoxTable(Tbl: TTable; Db: TDatabase):DBIResult; var TblDesc: CRTblDesc; begin Result := DBIERR_NA; FillChar(TblDesc, SizeOf(CRTblDesc), 0); StrPCopy(TblDesc.szTblName, Tbl.TableName); TblDesc.bPack := True; Result := DbiDoRestructure(Db.Handle, 1, @TblDesc, nil, nil, nil,False); end;
Таблица, передаваемая в качестве второго параметра, должна быть закрыта.
Если вам необходимо послать сообщение Windows (или ваше собственное) какому-либо компоненту, воспользуйтесь методом Perform. Этот метод вводится в классе TControl, поэтому его имеют все визуальные компоненты. Метод Perform посылает сообщение непосредственно оконной процедуре компонента, минуя очередь сообщений Windows, в отличие от функций API SendMessage и PostMessage, которые посылают сообщения в очередь. Пример:
Panel1.Perform(WM_LButtonDown, 0, MakeLong(1, 1)); Panel1.Perform(WM_LButtonUp, 0, MakeLong(1, 1));
Если в вашей программе происходит добавление большого количества строк в компонент Memo, то операцию можно значительно ускорить. Для этого нужно вызвать метод BeginUpdate перед добавлением строк, и метод EndUpdate после добавления:
Memo1.Lines.BeginUpdate; ... {добавляем множество строк ...} ... Memo1.Lines.EndUpdate;
Вышесказанное в равной степени относится к компоненту ListBox и его свойству Items, а также к другим компонентам, которые имеют свойства типа TStrings.
Тел: +7 (095)
944-XXXX E-mail: maxico@i-connect.ru Copyright © 1998 |