Отправляет email-рассылки с помощью сервиса Sendsay

Delphi - проблемы и решения

  Все выпуски  

Проблемы и решения в Delphi #38


Служба Рассылок Subscribe.Ru

Проблемы и решения в Delphi - выпуск 38 от 29.11.2001.


Небо синее, пламя алое
на Тартугас ты - усталая.


ВСЕ ВОПРОСЫ СПРОСИТЬ ПРЕДЛОЖИТЬ АРХИВЫ СКОЛЬКО НАС


Доброго Вам времени суток уважаемый читатель.

А на Тартугас отослали программистку :)

Подскажите, может кто в курсе, а то от Subscribe правды не добьешься -
у всех все нормально с подпиской по почте? Например на команду
Help или List в сторону subscribe@subscribe.ru приходит то, что надо?

Сегодня в выпуске :
~~~~~~~~~~~~~~~~~~~
1. Очередные вопросы.
2. Отвеченные вопросы.
~~~~~~~~~~~~~~~~~~~



1. Очередные вопросы.
---------------------


Вопрос 575: 

От: Виктор Афанасьев

Создаю подобие справочной системы. Использую InterBase как СУБД и
TWebBrowser как основной компонент представления информации. Чтобы не
мучиться со вставкой в HTML графики и других объектов планирую
использовать
MIME формат и хранить полностью весь документ в базе данных. Но есть
проблема: при загрузке документа из потока (TMemoryStream) в WB
отображается
его исходный HTML код а не вид документа как он должен быть. Приходится
предварительно сохранять документ во временный файл на диске а только
потом
загружать в WB. Но это далеко не лучший выход. В чем проблема понять не
могу
Если есть варианты был бы очень благодарен.



Ответить.

Ответ 1:


Вопрос 576: 

От: kovchan

Не подскажите, как вытащить информацию из имеющегося метафайла (*.wmf)?
Допустим, это рисунок прямоугольника. Как узнать координаты его узлов?
Вопрос, наверное, не совсем по Дельфи, но тем не менее.



Ответить.

Ответ 1:


Вопрос 577: 

От: LYNX

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


Ответить.

Ответ 1:


Вопрос 578: 

От: Andrew

Как послать системе Win2000 сообщение о завершении работы?


Ответить.

Ответ 1:


Вопрос 579: 

От: NEN

Уважаемые кодеры, помогите в решении задачи: как прочесть кусок памяти
за пределами своей проги в NT (именно) виндах. Любые попытки
заканчиваются Нарушением доступа. ReadProcessMemory - НЕРАБОТАЕТ воще
(в НТ).


Ответить.

Ответ 1:


Вопрос 580: 

От: luba

Как заставить DBGrid сортировать данные по щелчку на заголовке столбца?


Ответить.

Ответ 1:


Вопрос 581: 

От: Sir Antony


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

Дык вот не подскажите ли как мне проиграть файл через модем в
телефонную сеть. Есть ли у кого исходники отдельных частей или полной
задачи - очень прошу, выручите пожалуйста. Буду рад любой информации.
За доку и линки тоже заранее спасибо.

Оборудование Voice WinModem. Если это упирается в какие-либо параметры
системы мне тоже нужно знать.


Ответить.

Ответ 1:


Вопрос 582: 

От: -= MTsv =-


У меня вопрос:
Как по нажатию кнопки "ВЛЕЗТЬ" в контекстное меню всех файлов
(только файлов, каталоги не нужны) ???
Т.е. на любом файле жмешь правую кнопку и там в меню
"Запустить MyProg.exe"


Ответить.

Ответ 1:


Вопрос 583: 

От: Andy

Уважаемые программисты, не подскажете в чем ошибка?
Вот пример кода
DataModule2.Table1.Filter:=
'Bithday>'+DateToStr(DateTimePicker1.date)+'AND Bithday<'
+DateToStr(DateTimePicker2.date);
DataModule2.Table1.Filtered:=true;
Пишет ошибку "Invalid filter expression character '.'"


Ответить.

Ответ 1:


Вопрос 584: 

От: Gavrilenko


Посоветуйте, как программно определить наличие индексов в DBF таблицах



Ответить.

Ответ 1:


Вопрос 585: 

От: Зайцев Александр

Есть база данных в Btrieve.
Существуют ли компоненты для прямой работы с Btrieve в Delphi?
И если их нет , то где найти драйвера для BDE или ODBC?
Версия Btrieve 6.15


Ответить.

Ответ 1:



2. Отвеченные вопросы.
----------------------


Вопрос 568: 

От: Воробьев Сергей

Подскажите как с помощью Open Tools Api, отследить момент, когда идет
переключение между формами, не прибегая к таймеру и не вешая на OnTimer
ToolServices.GetCurrentFile?


Ответить.

Ответ 1:

Вопрос 569: 

От: Т

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


Ответить.

Ответ 1:
Цветные ячейки в StringGrid / DBGrid.
Автор: Alex Schlecht
StringGrids / DBGrids с цветными ячейками смотрятся очень красиво, и
Вы можете информировать пользователя о важных данных внутри Grid.
Совместимость: все версии Delphi
К сожалению, невозможно применить один и тот же метод к StringGrids и
к DBGrids. Итак сперва рассмотрим как это сделать в StringGrid:

1. StringGrid
=============
Для раскрашивания будем использовать событие "OnDrawCell". Следующий код показывает, как сделать в Grid красный бэкраунд. Бэкграунд второй колонки будет зелёным.

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);

const //здесь определяем Ваш цвет. Так же можно использовать цвета по умолчанию.
clPaleGreen = TColor($CCFFCC);
clPaleRed = TColor($CCCCFF);

begin

//Если ячейка получает фокус, то нам надо закрасить её другими цветами
if (gdFocused in State) then begin
StringGrid1.Canvas.Brush.Color := clBlack;
StringGrid1.Canvas.Font.Color := clWhite;
end
else //Если же ячейка теряет фокус, то закрашиваем её красным и зелёным

if ACol = 2 //Вторая колонка будет зелёной , другие - ячейки красными
then StringGrid1.Canvas.Brush.color := clPaleGreen
else StringGrid1.canvas.brush.Color := clPaleRed;

//Теперь закрасим ячейки, но только, если ячейка не Title- Row/Column
//Естественно это завит от того, есть у Вас title-Row/Columns или нет.

if (ACol > 0) and (ARow>0) then
begin
//Закрашиваем бэкграунд
StringGrid1.canvas.fillRect(Rect);

//Закрашиваем текст (Text). Также здесь можно добавить выравнивание и т.д..
StringGrid1.canvas.TextOut(Rect.Left,Rect.Top,StringGrid1.Cells[ACol,ARow]);
end;
end;

Если Вы захотите чтобы цвет ячеек менялся в зависимости от значения в них, то можно заменить 3 линии (if Acol = 2 ......) на что-нибуть вроде этого

if StringGrid1.Cells[ACol,ARow] = 'highlight it'
then StringGrid1.Canvas.Brush.color := clPalered
else StringGrid1.canvas.brush.Color := clwhite;

Ну а теперь давайте раскрасим DBGrids:

2. DBGrid
=========
С DBGrids это делается намного проще. Здесь мы будем использовать событие "OnDrawColumnCell". Следующий пример разукрашивает ячейки колонки "Status" когда значение НЕ равно "a".
Если Вы хотите закрасить целую линию, то достаточно удалить условие "If..." (смотрите ниже)

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn;
State: TGridDrawState);
const
clPaleGreen = TColor($CCFFCC);
clPaleRed = TColor($CCCCFF);
begin

if Column.FieldName = 'Status' then //Удалите эту линию, если хотете закрасить целую линию

if Column.Field.Dataset.FieldbyName('Status').AsString <> 'a'
then
if (gdFocused in State) //имеет ли ячейка фокус?
then dbgrid1.canvas.brush.color := clBlack //имеет фокус
else dbgrid1.canvas.brush.color := clPaleGreen; //не имеет фокуса

//Теперь давайте закрасим ячейку используя стандартный метод:
dbgrid1.DefaultDrawColumnCell(rect,DataCol,Column,State)
end;
Вот и всё. Не правда ли красиво ?
Ответ 2:
Фрагмент кода моей программы - в зависимости от значения в поле
taPlatAnswerType
рисует строку белам цветом на красном фоне


procedure TfmMain.dgPlatDrawColumnCell(Sender: TObject; const Rect:
TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
with dgPlat.Canvas do
begin
if (taPlatAnswerType.AsString = 'b') and not (gdFocused in State)
then
// Условие какую строку надо рисовать по другому
begin
Brush.Color := clRed;
Font.Color := clWhite;
FillRect(Rect);
TextOut(Rect.Left, Rect.Top, Column.Field.Text);
end
else
dgPlat.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
end;

Вопрос 570: 

От: Alex Zhuravlev

Как проверить наличие установленного шрифта и как из программы
установить свой шрифт



Ответить.

Ответ 1:


Вопрос 571: 

От: Alex Zhuravlev

Можно ли получить доступ к портам ввода-вывода, памяти по абсолютному
адресу (например D0000-D7000), перехватьить прерывание. Должны ведь быть
какие-то ворота...


Ответить.

Ответ 1:
Если уж Вы пишете свои программы, то считается хорошим тоном, чтобы
Ваши программы были написаны
по правилам данной операционной системы (Windows, Linux и т.д.).
В многозадачных операционных системах
постулируется, что программы пользователя, работающие в третьем кольце
защиты, напрямую не имеют
доступа к системным ресурсам (физическая память, порты, прерывания).
Программы пользователя ДОЛЖНЫ
иметь доступ к системным ресурсам ТОЛЬКО через интерфейс пользователя
(API, Application User Interface).
И это логически оправдано, т.к. все системные ресурсы являются
разделяемыми и только система должна
отслеживать захват того или иного ресурса работающим приложением.
Итак, в Windows NT и Юникс-подобных системах программа пользователя
не имеет никакого прямого доступа к
системным ресурсам. Windows-9х, как всем известно, не была "доведена до
ума" разработчиками. И если к физической
памяти и прерывания программа пользователя здесь не имеет доступа, то к
портам ввода-вывода определенный доступ
все же имеется (если, конечно, эти порты не виртуализированы системой).
Если Вы используете в Вашем компьютере
какой-то Ваш контроллер и в системе нет драйвера для этого устройства,
то Вы можете обратиться к его портам,
используя обычную ассемблерную вставку:

mov dx, My_Port
in al, dx
; или
out dx, al

Но это, все-таки, считается дурным тоном в программировании. Если уж Вам необходимо использовать
системные ресурсы, пишите драйверы (vxd - для Win-9x, WDM для NT).


Вопрос 572: 

От: vj

Есть умные люди которые могут помочь определить версию MS-DOS? Только
не говорите, что ее можно определить с помощью стандартной API-функции
"GetVersion", она уже давно не работает под 32-битными Delphi. В связи
с этим, Майкрософт рекомендует использовать ассемблер. Я попытался
подобрать эквивалент на Delphi, но столкнулся с проблемой
инициализации ассемблерной функции DOS3Call. Где и как ее
инициализировать? При замене эквивалента int 21h вместо DOS3Call
выдается ошибка: "программа KRNL386.exe выполнила недопустимую..." и
т.д. Вот алгоритм:

procedure TForm1.Button1Click(Sender: TObject);
var
nMajor, nMinor, nOEMNumber: Byte;
begin
asm
mov ax, 3000h
call DOS3Call {int 21h}
mov nMajor, al
mov nMinor, ah
mov nOEMNumber, bh
end;
Label1.Caption:=Format('%d.%d.%d',[nMajor, nMinor, nOEMNumber]);
end;


Ответить.

Ответ 1:
// Delphi 5.0 WIN2k pro
// dos amp& win ver. really works
procedure TForm1.BitBtn1Click(Sender: TObject);
var
WinV: Word;
DosV: Word;

begin
WinV := GetVersion and $0000FFFF;
DosV := GetVersion shr 16;
Label1.Caption := IntToStr(Hi(DosV))+'.'+IntToStr(Lo(DosV));
Label2.Caption := IntToStr(Lo(WinV))+'.'+IntToStr(Hi(WinV));

end;


Вопрос 573: 

От: Savinov

Подскажите пожалуйста, как сделать, чтоб программа в панели задач
возле часов ( как бы резидентно) или чтоб она вообще не была видна в
панели задач :)))


Ответить.

Ответ 1:
Есть в библиотеке RX компонент RXTrayIcon, он выводит в SysTray иконку
приложения и обрабатывает клики на ней. А что бы приложение не было видно в
TaskBar, можно делать так
Application.Minimize;
ShowWindow(Application.Handle, SW_HIDE);

а для того что бы показать
Application.Restore;
Application.BringToFront;

Ответ 2:
Можно сделать следующим образом:

program Project1;

uses
Forms,
Windows,
unit1 in 'unit1.pas' {Form1},

{$R *.RES}
var
ExtendedStyle : integer;

begin
Application.Initialize;
ExtendedStyle:=GetWindowLong(application.Handle, GWL_EXSTYLE);
SetWindowLong(Application.Handle, GWL_EXSTYLE, ExtendedStyle or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

Но здесь есть проблема с завершением при shutdown Windows, надо
отлавливать WM_QueryEndSession и применять halt.

Можно сделать как-бы сервисное приложение даже в Win'98, его не будет
видно при нажатии Ctrl+Alt+Del:

Объявляешь функцию:
function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL';


Применяешь в любом месте:
RegisterServiceProcess(GetCurrentProcessID, 1); //скрыл процесс
RegisterServiceProcess(GetCurrentProcessID, 0); //показал процесс

Ответ 3:
Чтоб засунуть прогу в трей (та самая "возле часов" :-)есть WinAPI
функция Sell_NotifyIcon.
Плюс куча компонентов :в RX , LMD, BU...
А форму пряч.(например OnCreate Application.ShowMainForm:=false)
Ответ 4:
Добавить иконку в tray:

uses ..., ShellAPI;

...

function TaskBarIcon(hWindow:THandle; ID:Cardinal;ICON:hIcon;
CallbackMessage:Cardinal; Tip:String; Mode:byte):Boolean;
var NID : TNotifyIconData;
begin
FillChar( NID, SizeOf( TNotifyIconData ), 0 );
with NID do begin
Wnd := hWindow;
uID := ID;
uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
uCallbackMessage := CallbackMessage;
hIcon := Icon;
if Length( Tip ) > 63 then SetLength( Tip, 63 );
StrPCopy( szTip, Tip );
cbSize := SizeOf( TNotifyIconData );
end;
case Mode of
0:Result := Shell_NotifyIcon( NIM_ADD, @NID );
1:Result := Shell_NotifyIcon( NIM_DELETE, @NID );
else Result := Shell_NotifyIcon( NIM_MODIFY, @NID );
end;
end;

Вызывать следующим образом:
const uc_TrayIconID=1;
um_TrayIconClick=WM_USER+1;

...
if TaskBarIcon(Form1,uc_TrayIconID,ExtractIcon(hinstance,PChar(ParamStr(0)),0),
um_TrayIconClick,'QuickTip',0) then ShowMessage('Success');

но надо обрабатывать сообщение um_TrayIconClick


Вопрос 574: 

От: Ivan

Господа хорошие, очень прошу дать пример работы c внеэкранным буфером:
нарисовать в нём что-нибудь и кинуть на какой-либо объект (форму,
Image...).


Ответить.

Ответ 1:
Например так,

Дельфи под рукой нет, так что вот в таком виде

var
Buffer : TBitMap;

Допустим есть форма
По нужному событию можно выполнить следующий код (рисование на форма) :
try
Buffer := TBitMap.Create;
Buffer.Width := ClientWidth;
Buffer.Height := ClientHeight;
Buffer.Canvas. {чего то рисуешь}
Canvas.Draw(0,0, Buffer)
finally
Buffer.Free;
end;
Ответ 2:
Киньте на форму кнопку а в событе по щелчку вставьте этот кусок

// Создаем контекст дисплея
screenDC:=CreateDC('DISPLAY',nil,nil,nil);
// Создаем совместимый буфер
bufDC:=CreateCompatibleDC(ScreenDC);
// Создаем совместимый BitMap
bufBMP:=CreateCompatibleBitMap(screenDC,width,height);
// Выбираем его в контексте
SelectObject(bufDC,bufBMP);
// Сжимаем картинку дисплея до размеров формы
// и рисуем ее в буфере
StretchBlt(bufDC,0,0,width,height,screenDC,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),SRCCOPY);
// Копируем содержимое буфера на канву формы
BitBlt(Canvas.handle,0,0,width,height,bufDC,0,0,SRCCOPY);
// Обновляем
InvalidateRect(handle,nil,false);
// Очищаем память
DeleteObject(bufBMP);
DeleteDC(bufDC);
DeleteDC(BufBMP);
DeleteDC(screenDC);

не забыв про переменные перед словом begin
var
bufDC, ScreenDC : HDC;
bufBMP : HBITMAP;

Нажмите на кнопку раз десять. :)

KingPin from Severodvinsk
Ответ 3:
В Delphi зарезервирован класс TClipBoard. Предназначен специально для операций с буфером обмена.








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

Для интересующихся - немного о себе. Работаю на
железнодорожном транспорте ведущим программистом.
Основные мои разработки - это сбор и доставка клиентам
информации о вагонах и поездах: где находится(по России),
куда едет. В связи с этим программировал для e-mail,Socket,БД,ISAPI.

За сим прощаюсь - скорых Вам и качественных программ.

Автор рассылки - Дмитрий.
ICQ - 89533941.

ВСЕ ВОПРОСЫ СПРОСИТЬ ПРЕДЛОЖИТЬ АРХИВЫ СКОЛЬКО НАС



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное