procedure TForm3.DBBTCustomDrawCell(Sender: TcxCustomGridTableView;
ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
var ADone: Boolean);
var
idx_DATA2 : Integer;
begin
{Основной обработчик отрисовки}
TMyDrawEvent.MyCustomDrawCell(Sender,ACanvas,AViewInfo,ADone);
idx_DATA2 := GetIndex('_DATA2');
if AViewInfo.Item.Index = idx_DATA2 then
TMyDrawEvent.HighlightMiltiTextUseCustomDrawCell(Edit1.Text,
Sender, ACanvas, AViewInfo, ADone);
end;
Класс
Type
TMyDrawEvent = class(TObject)
public
class procedure MyCustomDrawCell(Sender: TcxCustomGridTableView;
ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo;
var ADone: Boolean);
// Отрисовка подсветки текста при поиске
class procedure HighlightMiltiTextUseCustomDrawCell(AText: string;
Sender: TcxCustomGridTableView;
ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo;
var ADone: Boolean);
end;
*****
class procedure TMyDrawEvent.HighlightMiltiTextUseCustomDrawCell(AText: string;
Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
var
R: TRect;
H: Integer;
brushColor, fontColor: TColor;
procedure CanvasInitDefault;
begin
ACanvas.Font.Style := [];
ACanvas.Font.Color := fontColor;
ACanvas.Brush.Color := brushColor; //$0080FF80;
end;
procedure CanvasInitSelection;
begin
ACanvas.Font.Style := [];
ACanvas.Font.Color := clBlack; //Sender.LookAndFeelPainter.DefaultSelectionTextColor;
ACanvas.Brush.Color := clYellow; //Sender.LookAndFeelPainter.DefaultSelectionColor;
end;
function GetLengthBlock(Text : String; CanvasSize : Integer; out BlockWidth : Integer) : Integer;
var
I : Integer;
S : string;
begin
Result := 0;
BlockWidth:= 0;
I := Length(Text);
while true do
begin
if I < 0 then Exit;
S := Copy(Text, 1, I);
BlockWidth := ACanvas.TextWidth(S);
if BlockWidth > CanvasSize then
begin
Dec(I);
Continue;
end
else
begin
Result := I;
exit;
end
end;
end;
procedure SetRectOutput(var OutRect: TRect; const AreaRect : TRect; const wBlock: Integer);
begin
OutRect.Left := AreaRect.left;
OutRect.Top := AreaRect.Top;
OutRect.Width := wBlock;
OutRect.Bottom := AreaRect.Top + H;
end;
var
AreaRect, OutRect: TRect;
posFind, lT, lSearch, wSearch, wS: Integer;
sTextAll, sSearch, sBlock, S: string;
p, wBlock : Integer;
begin
R := AViewInfo.Bounds; // Общая область
sTextAll := AViewInfo.Text; // Текст общий
sSearch := AText; // поисковый запрос
posFind := AnsiPos(AnsiUpperCase(sSearch), AnsiUpperCase(sTextAll));
if posFind < 1 then Exit;
ADone := True;
// Цвет и канва
fontColor := ACanvas.Font.Color;
brushColor := ACanvas.Brush.Color;
// Затираем все
ACanvas.FillRect(R);
// Высота текста
H := ACanvas.TextHeight(sTextAll);
// Основная область отрисовки
AreaRect.Left := R.Left + 1;
AreaRect.Top := R.Top + 2;
AreaRect.Right := R.Right - 1;
AreaRect.Bottom := R.Bottom - 2;
CanvasInitDefault;
sBlock := Copy(sTextAll, 1, PosFind-1);
if sBlock <> '' then
begin
repeat
// Нужно определить сколь символов влезает в блок текста
p := GetLengthBlock(sBlock, AreaRect.Width, wBlock);
s := Copy(sBlock,1, p);
SetRectOutput(OutRect, AreaRect,wBlock);
ACanvas.Canvas.TextRect(OutRect, OutRect.Left, OutRect.Top, s);
Delete(sBlock, 1, p);
// текст в основной блок не влез, сдвигает вниз
if sBlock <> '' then
begin
Inc(AreaRect.Top, H);
AreaRect.Left := R.Left + 1;
if (AreaRect.Bottom - AreaRect.Top) < H then Exit;
end
else
Inc(AreaRect.Left, wBlock)
until (sBlock = '');
end;
CanvasInitSelection;
sBlock := sSearch;
repeat
// Нужно определить сколь символов влезает в блок текста
p := GetLengthBlock(sBlock, AreaRect.Width, wBlock);
s := Copy(sBlock,1, p);
SetRectOutput(OutRect, AreaRect,wBlock);
ACanvas.Canvas.TextRect(OutRect, OutRect.Left, OutRect.Top, s);
Delete(sBlock, 1, p);
// текст в основной блок не влез, сдвигает вниз
if sBlock <> '' then
begin
Inc(AreaRect.Top, H);
AreaRect.Left := R.Left + 1;
if (AreaRect.Bottom - AreaRect.Top) < H then Exit;
end
else
Inc(AreaRect.Left, wBlock)
until (sBlock = '');
CanvasInitDefault;
sBlock := Copy(sTextAll, PosFind + Length(sSearch), Length(sTextAll));
if sBlock <> '' then
begin
repeat
// Нужно определить сколь символов влезает в блок текста
p := GetLengthBlock(sBlock, AreaRect.Width, wBlock);
s := Copy(sBlock,1, p);
SetRectOutput(OutRect, AreaRect,wBlock);
ACanvas.Canvas.TextRect(OutRect, OutRect.Left, OutRect.Top, s);
Delete(sBlock, 1, p);
// текст в основной блок не влез, сдвигает вниз
if sBlock <> '' then
begin
Inc(AreaRect.Top, H);
AreaRect.Left := R.Left + 1;
if (AreaRect.Bottom - AreaRect.Top) < H then Exit;
end
else
Inc(AreaRect.Left, wBlock)
until (sBlock = '');
end;
end;
среда, 25 февраля 2026 г.
Полезняшки. DevExpress Custom draw cell - подсветка поисковой строки в ячейке
Подсветка поисковой строки в CxGrid ячейке
код для включения подсветки
вторник, 22 ноября 2022 г.
Полезняшки: CadesCom. Подписание и проверка XML (XMLDSig) по GOST R 34.10-2012 256 bit
unit main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, CAdESCOM_TLB, CAPICOM_TLB, ComObj,
ActiveX, oleauto, EncdDecd;
Const
SUBJECT = 'Иванов Иван Иванович';
CAPICOM_CURRENT_USER_STORE = 2;
CAPICOM_MY_STORE = 'My';
CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2;
CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1;
CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED = 0;
CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING = 1;
// Криптопровайдер: Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider
signMethod = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256';
digestMethod = 'urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256';
type
TForm3 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
Procedure AddLog(S : String);
public
{ Public declarations }
function GetCertificateBySubjectName(certSubjectName : String) : ICPCertificate;
function SignCreate(Certificate : ICPCertificate; dataToSign : WideString) : WideString;
function Verify(SignedMessage : WideString) : boolean;
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure TForm3.AddLog(S: String);
begin
Memo1.Lines.Add(S);
end;
procedure TForm3.Button1Click(Sender: TObject);
var
Certificate : ICPCertificate;
fnXMLSource, fnXMLSigned : string;
SL : TStringList;
begin
Memo1.Clear;
Certificate := GetCertificateBySubjectName(SUBJECT);
if Certificate= nil then Exit;
fnXMLSource := ExtractFilePath(ParamStr(0)) + 'XML\test_canon.xml';
fnXMLSigned := ExtractFilePath(ParamStr(0)) + 'XML\test_signed.xml';
try
SL := TStringList.Create;
if FileExists(fnXMLSource) then
begin
SL.LoadFromFile(fnXMLSource);
AddLog('-------------------------------------------------------------------');
AddLog('XML для подписания');
AddLog('-------------------------------------------------------------------');
AddLog(SL.Text);
SL.Text := SignCreate(Certificate, SL.Text);
AddLog('-------------------------------------------------------------------');
AddLog('XML sign');
AddLog('-------------------------------------------------------------------');
AddLog(SL.Text);
SL.SaveToFile(fnXMLSigned);
end;
if FileExists(fnXMLSigned) then
begin
SL.LoadFromFile(fnXMLSigned);
AddLog('-------------------------------------------------------------------');
AddLog('XML проверка подписания');
AddLog('-------------------------------------------------------------------');
if Verify(SL.Text) then
AddLog('Подпись валидна!')
else
AddLog('Подпись недействительна!')
end;
finally
if Assigned(SL) then FreeAndNil(SL);
end;
end;
function TForm3.GetCertificateBySubjectName(certSubjectName : String): ICPCertificate;
var
Store : CPStore; //IStore3
Certificates : ICertificates2;
begin
Store := CoCPStore.Create;
Store.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
Certificates := Store.Certificates as ICertificates2;
Certificates.Find(CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, certSubjectName, True);
if Certificates.Count = 0 then
begin
AddLog('Сертификат не найден: SN=' + certSubjectName);
Result := nil;
Exit;
end
else
begin
AddLog('Сертификат найден: SN=' + certSubjectName);
Result := IInterface(Certificates.Item[1]) as ICPCertificate;
AddLog('Валидность: ' + DateToStr(Result.ValidFromDate) + '-' + DateToStr(Result.ValidToDate));
Store.Close();
end;
end;
function TForm3.SignCreate(Certificate: ICPCertificate; dataToSign: WideString): WideString;
var
Signer : ICPSigner;
SignedXML : ISignedXML;
begin
// Создаем объект CAdESCOM.CPSigner
Signer := CoCPSigner.Create;
Signer.Certificate := Certificate;
// Создаем объект CAdESCOM.SignedXML
SignedXML := CoSignedXML.Create;
SignedXML.Content := dataToSign;
// Указываем тип подписи - в данном случае вложенная
SignedXML.SignatureType := CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED;
// Указываем алгоритм подписи
SignedXML.SignatureMethod := signMethod;
// Указываем алгоритм хэширования
SignedXML.DigestMethod := digestMethod;
try
Result := SignedXML.Sign(Signer, '');
except
on E: Exception do
begin
AddLog('Ошибка подписания: ' + E.Message);
end;
end;
end;
function TForm3.Verify(SignedMessage : WideString) : boolean;
var
SignedXML : ISignedXML;
begin
// Создаем объект CAdESCOM.SignedXML
SignedXML := CoSignedXML.Create;
try
SignedXML.Verify(SignedMessage,'');
Result := true;
except
on E: Exception do
begin
AddLog('Ошибка проверки ЭЦП: ' + E.Message);
Result := False;
end;
end;
end;
end.
четверг, 27 февраля 2020 г.
OTL на заметку: параллельное выполнение функции в потоках, каждый со своими параметрами
Сама идея:
Запустит несколько паралельных потоков для выполнения некой общей задачи, причем каждый поток должен получить свои параметры для работы.
Применение на будущее: например одновременно сканирование файлов в нескольких директориях, понятно что имя директории для сканирования для каждого потока должно быть свое. Хоть и алгоритм сканирования общий.
Демо: передача параметров через блокирующую коллекцию, использование параметров через record (обертка), передаются два параметра частота и длительность, функция выполняющаяся в потоке получает эти параметры и 10 раз проигрывает сигнал с такой частотой и длительностью.
Потоков на запуск 4, работают одновременно 2....
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
OTLParallel, OtlTaskControl, OtlCollections, OtlCommon;
type
TParametersForProc = record
Hz : Integer;
Duration : Integer;
end;
TForm3 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
Join : IOmniParallelJoin;
CollectionParams : IOmniBlockingCollection;
public
{ Public declarations }
procedure JoinProcExecute;
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
procedure Go(Hz, Duration : Integer);
var
I: Integer;
begin
for I := 0 to 10 do
begin
Sleep(1000);
Winapi.Windows.Beep(Hz, Duration);
end
end;
procedure TForm3.JoinProcExecute;
var
Value : TOmniValue;
ParamProc : TParametersForProc;
begin
// Взять из коллекции параметры
CollectionParams.Take(Value);
// Преобразовать обратно
ParamProc := Value.Unwrap;
// Запустить процедуру с переданными параметрами
Go(ParamProc.Hz, ParamProc.Duration);
// вывести параметры
Memo1.Lines.Add(Format('Hz : %d; duration: %d',[ParamProc.Hz, ParamProc.Duration]));
end;
procedure TForm3.Button1Click(Sender: TObject);
var
arrayProc : array of TProc;
I: Integer;
Value : TOmniValue;
ParamProc : TParametersForProc;
begin
CollectionParams := TOmniBlockingCollection.Create;
SetLength(arrayProc, 4);
for I := Low(arrayProc) to High(arrayProc) do
begin
// Для каждого потока свои параметры, поэтому перед запуском потоков
// в коллекцию добавляем параметры, функция выполняющаяся в потоке будет
// брать параметр для себя из коллекции
ParamProc.Hz := (I+1) * 1000;
ParamProc.Duration := (I+1) * 20;
// обернуть рекорд к TOmniValue
Value := TOmniValue.Wrap(ParamProc);
// Добавим в параметры
CollectionParams.Add(Value);
arrayProc[i] := JoinProcExecute;
end;
CollectionParams.CompleteAdding; // добавление завершено
// NumTasks(2) - два потока выполняются одновременно
Join := Parallel.Join(arrayProc).NumTasks(2).NoWait.Execute; // запуск параллельных потоков
end;
end.
среда, 26 февраля 2020 г.
Полезняшки: Использование анонимных методов в Delphi в качестве обработчиков событий....
Сама идея:
Использовать классические обработчики событий, через анонимные методы. То есть сократить количество кода в обработчиках, там где реакцией на событие должно быть исполнение немногих строк кода.
Например, по событию нужно просто подать сигнал, или вывести сообщение.
Избавиться от объявления процедур обработки в классе, вызывающих замусоривание листинга.
Использовать классические обработчики событий, через анонимные методы. То есть сократить количество кода в обработчиках, там где реакцией на событие должно быть исполнение немногих строк кода.
Например, по событию нужно просто подать сигнал, или вывести сообщение.
Избавиться от объявления процедур обработки в классе, вызывающих замусоривание листинга.
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TOnNotify = reference to procedure; // анонимный метод
TDemoNotify = class
private
fOnNotify: TOnNotify;
public
procedure SendNotify;
published
property OnNotify : TOnNotify read fOnNotify write fOnNotify;
end;
TfrmNotify = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
demo : TDemoNotify;
public
{ Public declarations }
procedure _onNotify;
end;
var
frmNotify: TfrmNotify;
implementation
{$R *.dfm}
{ TDemoNotify }
procedure TfrmNotify.FormCreate(Sender: TObject);
begin
demo := TDemoNotify.Create;
end;
procedure TfrmNotify.FormDestroy(Sender: TObject);
begin
if Assigned(demo) then FreeAndNil(demo);
end;
procedure TfrmNotify._onNotify;
begin
ShowMessage('Сработало классика!');
end;
procedure TDemoNotify.SendNotify;
begin
if Assigned(fOnNotify) then fOnNotify;
end;
procedure TfrmNotify.Button1Click(Sender: TObject);
begin
// Классический подход
demo.OnNotify := _onNotify;
demo.SendNotify;
end;
procedure TfrmNotify.Button2Click(Sender: TObject);
begin
// Обработчик через анонимную функцию
demo.OnNotify :=
procedure
begin
ShowMessage('Сработало анонимная процедура!');
end;
demo.SendNotify;
end;
end.
вторник, 14 января 2014 г.
Delphi и Android. Странная бага в TSQLConnection dbExpress .
Решил прикрутить SQLite к программе на андроид.
Делал все как по инструкции Using SQLite (iOS_and_Android), однако когда у свойства Connected
объекта TSQLConnection выставляю True и запускаю прогу на устройство, программа android уходит в черный экран и зависает до появления предложения ОС Android о закрытии зависшего приложения.
При этом в дизайнере все показывается нормально (я имею ввиду информацию с БД - в List.Item - Дачный дом берется из записи таблицы БД). Если отключить подключение к БД (Connected - False) и запустить приложение то все нормально.
В Deployment тоже все настроено по инструкции:
Код подключения для к БД для Android аналогичный примеру.
procedure TfrmMain.SQLConnectionBeforeConnect(Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
SQLConnection.Params.Values['ColumnMetadataSupported'] := 'False';
SQLConnection.Params.Values['Database'] :=
TPath.Combine(TPath.GetDocumentsPath, 'Ksital.s3db');
{$ENDIF}
end;
В общем третий день чудеса. Может кто встречался с такой проблемой?
PS. Скриншот с эмулятора.
Делал все как по инструкции Using SQLite (iOS_and_Android), однако когда у свойства Connected
объекта TSQLConnection выставляю True и запускаю прогу на устройство, программа android уходит в черный экран и зависает до появления предложения ОС Android о закрытии зависшего приложения.
При этом в дизайнере все показывается нормально (я имею ввиду информацию с БД - в List.Item - Дачный дом берется из записи таблицы БД). Если отключить подключение к БД (Connected - False) и запустить приложение то все нормально.
В Deployment тоже все настроено по инструкции:
Код подключения для к БД для Android аналогичный примеру.
procedure TfrmMain.SQLConnectionBeforeConnect(Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
SQLConnection.Params.Values['ColumnMetadataSupported'] := 'False';
SQLConnection.Params.Values['Database'] :=
TPath.Combine(TPath.GetDocumentsPath, 'Ksital.s3db');
{$ENDIF}
end;
В общем третий день чудеса. Может кто встречался с такой проблемой?
PS. Скриншот с эмулятора.
четверг, 9 января 2014 г.
Android и Delphi XE. Хранение пользовательских данных Preferens. Аналог INI-файлов Windows
Пользовательские данные в Androide могут хранится либо в пользовательских файлах Preferens либо в БД Sql Lite, либо в обычных файлах (например на SD-карте). Для начала рассмотрим хранение в пользовательских файлах Preferens поддерживающихся OC Android.Код простой:
unit Main; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Edit, FMX.DateTimeCtrls, AndroidApi.Jni.JavaTypes, AndroidApi.Jni.App, AndroidApi.Jni.GraphicsContentViewText, FMX.Helpers.Android; type TForm1 = class(TForm) Edit1: TEdit; NumberBox1: TNumberBox; CalendarEdit1: TCalendarEdit; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } Prefs: JSharedPreferences; public { Public declarations } Procedure Save; end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.Button1Click(Sender: TObject); begin Save; end; procedure TForm1.FormCreate(Sender: TObject); begin // Cохранение данных. Сначала с помощью метода getSharedPreferences получаем объект sPref класса SharedPreferences, // который позволяет работать с данными (читать и писать). Константа MODE_PRIVATE используется для настройки доступа и означает, // что после сохранения, данные будут видны только этому приложению. // MyData - имя файла для хранения данных. Prefs := SharedActivity.getSharedPreferences(StringToJString('MyData'), TJActivity.JavaClass.MODE_PRIVATE); Edit1.Text := JStringToString(Prefs.getString(StringToJString('Edit1'), StringToJString(''))); NumberBox1.Value := Prefs.getFloat(StringToJString('NumberBox1'), 0); CalendarEdit1.Date := StrToDate( JStringToString(Prefs.getString(StringToJString('CalendarEdit1'), StringToJString('10.01.2014')))); end; procedure TForm1.FormDestroy(Sender: TObject); begin Save; end; procedure TForm1.Save; var Editor: JSharedPreferences_Editor; begin // Чтобы редактировать данные, необходим объект Editor – получаем его из sPref. Editor := Prefs.edit; Editor.putString(StringToJString('Edit1'), StringToJString(Edit1.Text)); Editor.putFloat(StringToJString('NumberBox1'), NumberBox1.Value); Editor.putString(StringToJString('CalendarEdit1'), StringToJString(DateToStr(CalendarEdit1.Date))); Editor.apply; end;
Помимо getSharedPreferences использовать getPreferences, если хотите не выдумывать имя файла. Имя файла будет задана автоматом по имени текущего окна.Использовать getSharedPreferences, нужно когда данные - общие для нескольких окон, а также если сами хотите выбирать имя файла для сохранения.
пятница, 25 октября 2013 г.
Полезняшки. Shell-расширения для файлов Delphi и Lazarus
Случайно нашел интересный проект http://code.google.com/p/delphi-dev-shell-tools/
который в контекстное меню для файлов .pas, .dpr, .inc, .pp, .dpk, . dproj, .frm, .fmx, .rc добавляет различные действия сильно облегчающие жизнь Delphi/Lazarus-программисту.
Причем все это гибко настраивается.
который в контекстное меню для файлов .pas, .dpr, .inc, .pp, .dpk, . dproj, .frm, .fmx, .rc добавляет различные действия сильно облегчающие жизнь Delphi/Lazarus-программисту.
Причем все это гибко настраивается.
вторник, 22 октября 2013 г.
Delphi XE5 разработка мобильных приложений. Некоторые заметки для осмысления. (Upd 2)
Некоторые наблюдения по итогам тестовых приложений для Android. Мой взгляд на разработку.
четверг, 17 октября 2013 г.
Первое приложение под Android, некоторые мысли вслух
Свершилось. Наконец-то я стал владельцем Android устройства в виде телефона Lenovo S750. И конечно же став им, решил попробовать написать свое первое приложение под новую платформу.
Итак прежде чем начать писать я столкнулся с тем, что мое устройство с 4'5 дюймовым экраном отсутствует в формах доступных устройств, я имею ввиду в выпадающем списке где выбираются для формы разрешение и внешний вид Android устройства. Ничего страшного - решил я, нарисую форму своего телефона в дизайнере мобильных устройств, заодно проставлю размеры разрешения экрана- так думал я входя в Tools - Options - Form Designer - Device Manager.
Итак прежде чем начать писать я столкнулся с тем, что мое устройство с 4'5 дюймовым экраном отсутствует в формах доступных устройств, я имею ввиду в выпадающем списке где выбираются для формы разрешение и внешний вид Android устройства. Ничего страшного - решил я, нарисую форму своего телефона в дизайнере мобильных устройств, заодно проставлю размеры разрешения экрана- так думал я входя в Tools - Options - Form Designer - Device Manager.
вторник, 10 июля 2012 г.
OTL, в продолжение темы
Давеча Александр Алексеев выложил в своем блоге клич о библиотеке OTL и предложил совместно с Александром Егоровым переводить книгу Приможа Габриельчича (Primož Gabrijelčič) о библиотеке OTL.
Одно время я занимался переводом статей об OTL c блога данного автора, до появления его книги. Формат мелких заметок блога не совсем устраивал меня и я попытался сделать свою компоновку материалов в виде книги. Конечно данная подборка очень существенно уступает книге самого автора в плане продуманности подачи материала и структуированности, но все же почти 80 страниц объединенного материала на русском языке не должны пропасть даром, даже если где то они и устарели.
Вообщем выкладываю свой вариант перевода тут
Одно время я занимался переводом статей об OTL c блога данного автора, до появления его книги. Формат мелких заметок блога не совсем устраивал меня и я попытался сделать свою компоновку материалов в виде книги. Конечно данная подборка очень существенно уступает книге самого автора в плане продуманности подачи материала и структуированности, но все же почти 80 страниц объединенного материала на русском языке не должны пропасть даром, даже если где то они и устарели.
Вообщем выкладываю свой вариант перевода тут
среда, 11 апреля 2012 г.
Шпаргалка. Использование Microsoft Script Control в приложениях - #3
Создание функции
В данной заметке продолжим разбираться с работой Script Control, мы разобрались, как создавать процедуры, теперь научимся создавать функции. На самом деле функции мы уже имеем создавать, как там, а очень просто – вспомним, чем отличается функция от процедуры. А тем, что процедура не возвращает никаких данных, значит, добавив в процедуру возможность, возвращение результата мы превратим ее в функцию.Шпаргалка. Использование Microsoft Script Control в приложениях - #2
Итак, продолжим:
Если вы внимательно посмотрите на предыдущую реализацию метода Invoke, вы заметите две функции, а именно CheckArgCount и IsVdalidTypeBSTR
Первая функция проверяет количество параметров переданных в процедуру и функцию и определена в базовом классе как
Если вы внимательно посмотрите на предыдущую реализацию метода Invoke, вы заметите две функции, а именно CheckArgCount и IsVdalidTypeBSTR
Первая функция проверяет количество параметров переданных в процедуру и функцию и определена в базовом классе как
вторник, 10 апреля 2012 г.
Шпаргалка. Использование Microsoft Script Control в приложениях - #1
Добрый день!
Поводом для этой шпаргалки стали мои мои попытки разобраться с работой MS Script Control.
Для начала оговорюсь сразу в этой заметке не будет детального описания работы для этого уже есть много материала в Интернете, например: "Использование Microsoft ScriptControl" ,
Здесь же пойдет речь о самой работе с Script Control, так сказать некоторые ньюансы его использования, предпологается что читатель уже имеет некоторое представление:
Поводом для этой шпаргалки стали мои мои попытки разобраться с работой MS Script Control.
Для начала оговорюсь сразу в этой заметке не будет детального описания работы для этого уже есть много материала в Интернете, например: "Использование Microsoft ScriptControl" ,
Здесь же пойдет речь о самой работе с Script Control, так сказать некоторые ньюансы его использования, предпологается что читатель уже имеет некоторое представление:
понедельник, 6 февраля 2012 г.
Полезняшки: DevExpress.cxVirtualVerticalGrid как средство редактирование и отображения данных таблицы БД
Добрый день!
В этом посте пойдет речь, о небольшой полезняшке позволяющий превратить стандартный DevExpress-овский компонент cxVirtualVerticalGrid в средство отображения и редактирования данных таблицы БД.
суббота, 4 февраля 2012 г.
Полезняшки. Загрузка файла в БД в виде внедренного OLE-объекта без использование стандартного OleContainer
Добрый день!
Недавно встала задача загружать файлы документов в БД (поле BLOB) в виде OLE-объекта, которого в дальнейшем можно вывести в стандартный OLE контейнер Delphi для просмотра и последующего редактирования.
Недавно встала задача загружать файлы документов в БД (поле BLOB) в виде OLE-объекта, которого в дальнейшем можно вывести в стандартный OLE контейнер Delphi для просмотра и последующего редактирования.
суббота, 5 ноября 2011 г.
Полезняшки: Всплывающие информационные окна
Добрый день!
Сегодня поговорим о полезняшках в нашей професии программиста. Одной из таких полезняшек для меня стали всплывающие информационные окна, наподобие тех что есть в QIP-e.
Вообще предыстория этих окон следующая, в одном моем проекте понадобились всплывающие окна, да не просто всплывающие а поддерживающие следующую функциональность:
- наличие кнопок-ответов
- возможность задания кнопки по умолчанию
- возможность автонажатия кнопок по истечению некоторого времени с отображением таймера обратного отчета
- группировка окон, заключающаяся в том, что при появлении нового всплывающего окна, оное окно не перекрывала существующие, а при удалении окна с экрана, окна текущие сортировались в некий порядок.
- раскраска окна по ситуации - "стандартное", "информационное", "окно сообщения об ошибке" и.т.д
- возможность одновременного закрытия всех окон
- возможность перетаскивания окон и изменения размеров
ну и прочие мелкие полезняшки.
четверг, 1 сентября 2011 г.
Образ продуктов от партнеров Embarcadero RAD Studio XE2 Partner DVD ISO
Образ продуктов от партнеров Embarcadero RAD Studio XE2 Partner DVD ISO
http://altd.embarcadero.com/download/radstudio/xe2/delphicbuilder_xe2_win_partner.iso
http://altd.embarcadero.com/download/radstudio/xe2/delphicbuilder_xe2_win_partner.iso
среда, 20 июля 2011 г.
Вышла новая версия OmniThreadLibrary 2.1
Вышла новая версия OmniThreadLibrary 2.1
Скачать ее можно либо тут либо с официального SVN проекта.
Вкратце, что появилось нового:
Добавлена поддержка исключений в методы Parallel.Future и Parallel.Join. так как эти методы претерпели существенные изменения, существует опасность проблем с ранее написанным кодом. Прежде, чем устанавливать новую версию проверьте history.txt и документацию в OtlParallel.pas для дополнительной информации по совместимости.
Вы также с выходом новой версии получаете полную UML диаграмму классов и методов OTL.
Добавлены новые демонстрационные примеры:
Скачать ее можно либо тут либо с официального SVN проекта.
Вкратце, что появилось нового:
Добавлена поддержка исключений в методы Parallel.Future и Parallel.Join. так как эти методы претерпели существенные изменения, существует опасность проблем с ранее написанным кодом. Прежде, чем устанавливать новую версию проверьте history.txt и документацию в OtlParallel.pas для дополнительной информации по совместимости.
Вы также с выходом новой версии получаете полную UML диаграмму классов и методов OTL.
Добавлены новые демонстрационные примеры:
- 43_InvokeAnonymous: - пример использования метода IOmniTaskControl.Invoke и IOmniTask.Invoke.
44_Fork-Join QuickSort: - пример реализации быстрой сортировки QuickSort используя Parallel.ForkJoin.
45_Fork-Join max: Выбор максимального элемента в массиве используя Parallel.ForkJoin.
46_Async: Демо для Parallel.Async.
47_TaskConfig: Демо для Parallel.TaskConfig.
четверг, 23 июня 2011 г.
Использование OmniThread Libray 2.0 (OTL 2.0) для создания многопоточных приложений. Настройка фоновых задач в OTLParallel
Простота параллелизма высокоуровневых фоновых задач библиотеки OmniThreadLibrary (модуль OtlParallel) проявляется при управлении несколькими частями независимого кода. Это хорошо показано в предыдущей части.
Однако при такой высокоуровневой обработке фоновых задач необходимы инструменты, позволяющие настраивать и регулировать эти задачи. Одним из примеров настройки является общение фоновой высокоуровневой задачи с главным потоком программы (основным потоком).
Ранее взаимодействие между фоновыми задачами и основным потоком программы, ложилось на плечи каналов связи, которые мы рассматривали ранее. Приходилось реализовать такие каналы вручную или опускаясь на низкий уровень блиотеки работать с CreateTask.
Однако начиная с выпуска 910, OtlParallel содержит намного более простой способ создания фоновых задачи и настройки их для коммуникации с владельцем (сиречь основным потоком программы).
среда, 4 мая 2011 г.
Коллекции во внешнем COM-сервере. Простое решение.
Добрый день дорогие коллеги!
В этой заметке пойдет речь о создании внешнего COM-сервера и реализации в нем простой коллекции. Что я подразумеваю под коллецией. Под ней я подразумеваю,то что некий COM сервер имеет грубо говоря некий набор данных к которым нужно получить доступ. А так как набор данных может быть разным то нужно предоставить пользователям возможность получать эти данные проходом по коллеции. Классическим примером может служить COM-сервер MS Excel который предоставляет пользователям коллецию рабочих листов IWorkSheet. Что-то подобное в простом решении мы сейчас и реализуем.
Подписаться на:
Сообщения (Atom)




