![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
На форме fSynch только ProgressBar
Код:
program WorkPlace;
uses
Vcl.Forms,
uMain in 'uMain.pas' {fMain} ,
uSynch in 'uSynch.pas' {fSynch};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TfSynch, fSynch);
Application.CreateForm(TfMain, fMain);
Application.Run;
end.Куда весь этот код обработки вписывать? в OnShow - форма не вырисовывается, но процесс загрузки идёт. Т.е. приложение зависает, потом появляется форма со 100% ProgressBar на секунду и сразу же Главное окно программы. |
|
#2
|
||||
|
||||
|
TThread...
|
|
#3
|
||||
|
||||
|
так http://zalil.ru/34738901 сойдет?
|
|
#4
|
||||
|
||||
|
с приветственной заставкой в которой кнопка (или MainMenu) - подключиться
|
|
#5
|
||||
|
||||
|
Похоже, автор плохо усвоил предыдущий урок. Я уже начинаю разочаровываться.
В приведенном коде проекта есть две фактические ошибки:
Как бы сделал я:
|
| Этот пользователь сказал Спасибо Freeman за это полезное сообщение: | ||
Uniq! (23.09.2013)
| ||
|
#6
|
||||
|
||||
|
Вообще сама по себе идея как-то подсчитывать прогресс выполнения обращения к БД, неудачна. Это касается и подключения и выполнения запросов. А вот как-то информировать пользователя о каком-то процессе - это нужно. Из многих виденных мной решений, наиболее удачным оказался прогрессбар в режиме пинг/понга запущенный в отдельном потоке.
Лично я выделяю под него в статусбаре приложения пустое место и как только возникает необходимость отобразить длительный процесс у меня он отображается, крутится пока не закончится процесс и снова скрывается. |
|
#7
|
||||
|
||||
|
Код:
screen.cursor:=crHourGlass; ... screen.cursor:=crDefault; да и все ![]() |
|
#8
|
||||
|
||||
|
Цитата:
С ошибками разбирался всю ночь. По поводу MainForm выяснил. Что касается обработки информации в OnCreate главной формы: Есть нюанс, что при загрузке данных используются и другие формы. Например выгрузка настроек из IniFil'a в форму fSettings. Т.е. её тоже нужно создать перед тем, как в неё выгружать информацию. Итоговый код: Код:
program WorkPlace;
uses uMain in 'uMain.pas' {fMain}; // все unit'ы
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TfMain, fMain);
Application.CreateForm(TfDM, fDM);
Application.CreateForm(TfNewTicket, fNewTicket);
Application.CreateForm(TfCheckClient, fCheckClient);
Application.CreateForm(TfSettings, fSettings);
Application.CreateForm(TfTicketInfo, fTicketInfo);
Application.CreateForm(TfNewClient, fNewClient);
Application.CreateForm(TfReport, fReport);
fSynch := TfSynch.Create(Application);
fSynch.Show;
fSynch.LoadData; // функция по примеру, который предложил NumLock
fSynch.Free;
Application.Run;
end.Код:
procedure TfSynch.LoadData;
var
IniF: TIniFile;
begin
IniF := TIniFile.Create(ExtractFilePath(Application.Exename) +
'/Settings.ini');
with fSettings do
begin
gPawnshop.Text := IniF.ReadString('General', 'Pawnshop', '');
gNum.Text := IntToStr(StrToInt('$' + IniF.ReadString('General', 'N', '')));
gNumM.Text := IntToStr(StrToInt('$' + IniF.ReadString('General',
'NM', '')));
// Connection
sDriver.Text := IniF.ReadString('Connection', 'Driver', '');
sServer.Text := IniF.ReadString('Connection', 'Server', '');
sPort.Text := IniF.ReadString('Connection', 'Port', '');
sUid.Text := IniF.ReadString('Connection', 'Uid', '');
end;
IniF.Free;
fDM.GlobalConn.ConnectionString := 'Driver=' + fSettings.sDriver.Text + ';' +
'Server=' + fSettings.sServer.Text + ';' + 'Port=' + fSettings.sPort.Text +
';' + 'UID=' + fSettings.sUid.Text + ';' +
'Database=gobseck;PWD=ХАРДКОЖЕНЫЙПАРОЛЬ;';
fSynch.pSynch.Properties.Text := 'Подключение к серверу: ' +
fSettings.sServer.Text + '. Пожалуйста, ждите...';
Application.ProcessMessages;
try
fDM.GlobalConn.Connected := true;
except
while fDM.GlobalConn.DataSetCount <> 0 do
fDM.GlobalConn.DataSets[0].Connection := fDM.LocalConn;
fDM.LocalConn.Connected := true;
end;
end;Процедуры AfterConnect для Global И Local connection идентичны (с точностью до имён): Код:
procedure TfDM.GlobalConnAfterConnect(Sender: TObject);
var
i: integer;
begin
for i := 0 to fDM.GlobalConn.DataSetCount - 1 do
begin
fSynch.pSynch.Properties.Text := 'Загрузка: ' +
fDM.GlobalConn.DataSets[i].Name;
fSynch.pSynch.Update;
fDM.GlobalConn.DataSets[i].Open;
fSynch.pSynch.Position := fSynch.pSynch.Position +
100 / fDM.GlobalConn.DataSetCount;
fSynch.pSynch.Update;
end;
end;Последний раз редактировалось Uniq!, 23.09.2013 в 13:45. |
|
#9
|
||||
|
||||
|
Цитата:
|
|
#10
|
||||
|
||||
|
а udl файлы не нравятся?
|
|
#11
|
||||
|
||||
|
Цитата:
Если речь идет про конфигурацию, нужно создать некий невизуальный класс TEnvironment, умеющий читать и сохранять себя в ini-файлы или куда нужно. Логически связанные элементы конфигурации можно оформить в подклассы, можно в записи, а можно и в свойства. Предварительно созданный и проинициализированный экземпляр TEnvironment по мере надобности передается формам и модулям данных, и они читают из него нужные настройки. Можете закидать меня помидорами, но TDataModule я считаю быдлокодерским компонентом. В Delphi он реализован неправильно: отсутствует возможность класть созданный в проекте экземпляр DataModule на форму, как это происходит с фреймами. Модуль данных должен быть невизуальным аналогом фрейма, а не нарушением агрегации, как сейчас. Цитата:
Другой явный образчик быдлокода -- обращение из события к самому себе через внешнюю переменную. Грубо говоря, в коде нужно везде поубирать обращения к fDM к чертовой матери. Цитата:
Цитата:
Последний раз редактировалось Freeman, 23.09.2013 в 16:55. |
|
#12
|
||||
|
||||
|
Нужны хорошие книжки. Я осилил около десятка за 10 лет. И кучу интернет ресурсов. О том, что такое Sender узнал только сегодня.
Что касается AfterConnect: Код:
procedure TfDM.DoAfterConnect(Sender: TObject);
var
i: integer;
Connection: TADOConnection;
begin
Connection := (Sender as TADOConnection);
for i := 0 to Connection.DataSetCount - 1 do
begin
fSynch.pSynch.Properties.Text := 'Загрузка: ' + GlobalConn.DataSets[i].Name;
fSynch.pSynch.Update;
Connection.DataSets[i].Open;
fSynch.pSynch.Position := fSynch.pSynch.Position + 100 / Connection.DataSetCount;
fSynch.pSynch.Update;
end;
end;Это типа класс. Сейчас ещё пару вёдер критики бы, было бы замечательно. Код:
unit uEnvironment;
interface
uses IniFiles;
type
TEnvironment = Class(TIniFile)
private
function GetNum: string;
function GetNumM: string;
function GetPawnshop: string;
procedure SetNum(const Value: string);
procedure SetNumM(const Value: string);
procedure SetPawnshop(const Value: string);
public
property Pawnshop: string read GetPawnshop write SetPawnshop;
property Num: string read GetNum write SetNum;
property NumM: string read GetNumM write SetNumM;
constructor Create(FilePath: string);
end;
var
Environment: TEnvironment;
implementation
{ TEnvironment }
constructor TEnvironment.Create(FilePath: string);
begin
end;
function TEnvironment.GetPawnshop: string;
begin
Environment.ReadString('General', 'Pawnshop', '');
end;
function TEnvironment.GetNum: string;
begin
Environment.ReadString('General', 'Num', '');
end;
function TEnvironment.GetNumM: string;
begin
Environment.ReadString('General', 'NumM', '');
end;
procedure TEnvironment.SetPawnshop(const Value: string);
begin
Environment.WriteString('General', 'Pawnshop', Value);
end;
procedure TEnvironment.SetNum(const Value: string);
begin
Environment.WriteString('General', 'Num', Value);
end;
procedure TEnvironment.SetNumM(const Value: string);
begin
Environment.WriteString('General', 'NumM', Value);
end;
{$R *.dfm}
end.Я так понимаю экземпляр этого класса должен быть доступен из всех форм (хотя чутьё подсказывает, что не из форм, а из процесса(сов)). Если отказываться от fDM (никогда, кстати не использовал, прочитал в книге, что на нём удобно держать тьму этих компонентов), то как тогда быть? Держать их на главной форме? Я уже думаю создать методичку для самого себя. Чтоб по полочкам всё разложить. Последний раз редактировалось Uniq!, 24.09.2013 в 02:27. |
|
#13
|
||||
|
||||
|
Цитата:
Цитата:
Возможно, мои слова про удаление обращений к fDM не совсем понятны. Имел в виду, что нужно удалить все точечные обращения к экземпляру fDM из кода самого fDM, чтобы он обращался к своим компонентам через Self. Слова про избавление от модуля данных можно пропустить мимо ушей. Delphi же не переделаешь. Фреймы в проекте не используются? |
|
#14
|
||||
|
||||
|
Памятка:
1) Создал Главную форму (на ней ADOConnection и все ADOTable) 2) Создал Splash-форму (исключил её из автосоздаваемых) 3) Обработчики ниже. В итоге, с учётом всего сказанного Freeman'ом по теме передачи данных из формы в форму и взаимодействия элементов получил: Код:
procedure TfMain.FormCreate(Sender: TObject);
var
i: integer;
begin
fSplash := TfSplash.Create(Application);
fSplash.Show;
fSplash.Update;
for i := 0 to Connection.DataSetCount - 1 do
Connection.DataSets[i].Open;
fSplash.Free;
end;Код:
procedure TfMain.DSBeforeOpen(DataSet: TDataSet);
begin
if fSplash <> nil then
fSplash.ShowProgressFor(DataSet.Name);
end;Код:
procedure TfSplash.ShowProgressFor(const LoadingItem: string);
begin
if LoadingItem <> '' then
ProgressText.Caption := Format('Загрузка %s...', [LoadingItem])
else
ProgressText.Caption := '';
ProgressText.Update;
end;Последний раз редактировалось Uniq!, 24.09.2013 в 03:05. |
|
#15
|
||||
|
||||
|
Цитата:
Код:
procedure TfMain.FormCreate(Sender: TObject);
var
i: integer;
begin
fSplash := TfSplash.Create(Application);
try
fSplash.Show;
fSplash.Update;
for i := 0 to Connection.DataSetCount - 1 do
Connection.DataSets[i].Open;
finally
fSplash.Free;
end;
end; |