Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (все версии) - часть 4

Модерирует : ShIvADeSt

ShIvADeSt (28-06-2009 02:10): Продолжение в http://forum.ru-board.com/topic.cgi?forum=33&topic=10477  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   

Mandor Sawall

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Maks150988

Код:
 function GetModuleInfo(szModuleName: PChar; dwMaxNameLen: DWORD; szGUID: PChar; dwMaxGUIDLen: DWORD; szModuleDescr: PChar; dwMaxDescrName: DWORD): BOOL; stdcall;
begin
  dwMaxNameLen   := strlen(PChar(TszModuleName)) + 1;
  //^^^ Ето ненужно, у вас параметр по стойност, не по адрес.
  StrLCopy(szModuleName, PChar(TszModuleName), dwMaxNameLen);
  dwMaxDescrName := strlen(PChar(TszModuleDescr)) + 1;
  //^^^ Ето тоже.
  StrLCopy(szModuleDescr, PChar(TszModuleDescr), dwMaxDescrName);
  dwMaxGUIDLen   := strlen(PChar(TszGUID)) + 1;
  //^^^ Ето тоже.
  StrLCopy(szGUID, PChar(TszGUID), dwMaxGUIDLen);
  Result := TRUE;
end;

Всего записей: 119 | Зарегистр. 20-03-2003 | Отправлено: 11:37 08-08-2008 | Исправлено: Mandor Sawall, 11:38 08-08-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вобщем код модуля такой сделал, но пока толком не исправлял:
Подробнее...
Но мне чего-то непонятно как отправить POST запрос username=blabla&password=blabla например на адрес http://ссылка, используя колбек функцию FN_HTTPDOWNLOAD. И все это выполнить через функцию GetAccountState. Вобщем как нужно прописать этот запрос,для меня неясно. Значения szAccount и szPassword передаются из программы и всталвяются в сам запрос.

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 17:11 08-08-2008
Pawo



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Нашел исходник высокоточного таймера, но при компиляции находит ошибку "Record, object or class required" в QW.QuadPart и ET.QuadPart. Как исправить ошибку?

Всего записей: 1105 | Зарегистр. 05-05-2007 | Отправлено: 17:38 08-08-2008
V1s1ter



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Pawo

Цитата:
Нашел исходник высокоточного таймера, но при компиляции находит ошибку "Record, object or class required" в QW.QuadPart и ET.QuadPart. Как исправить ошибку?

 
Пиши ULARGE_INTEGER(QW).QuadPart; вместо QW.QuadPart; и будет тебе счастье.

Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 18:03 08-08-2008
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Pawo
ну убери поля .QuadPart
 
т.е., например вместо
  ClockRate := QW.QuadPart;
пиши
  ClockRate := QW;
 
должно помочь...
если не поможет, тогда тоже убери эти поля, а вместо TLargeInteger используй Int64,
хотя это одно и тоже...

Всего записей: 24121 | Зарегистр. 06-12-2002 | Отправлено: 18:10 08-08-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ммм, неужели тут никто не может помочь... =) Я правда, если честно, не знаю, но уже прям принцип доделать плагин. Автор перевоначального исходника не желает давать свою реализацию, подозреваю что там уж слишком "подсудный" для него код то что возвратит сервер на его запрос о биллинге.
 
Вобщем ситуция такова. Есть:
 

Код:
 
type
  FN_HTTPDOWNLOAD = function(szURL : PChar; szMethod: PChar; szArgs: PChar; szReferrer : PChar; szContentType : PChar; pBuffer : pBYTE; dwMaxBufferLen : DWORD) : DWORD; stdcall;
 

 
И надо сделать через эту функцию обратного вызовы отправку POST запроса на сервер. Что-то типа этого.
 

Код:
 
//Состояние записи, получение данных
//const char* szAccount            - Логил
//const char* szPassword        - Пароль
//double* dBalance                - Баланс
//double* dOverdraft            - Овердрафт
//double* dActive                - Активные сессии (если есть)
//double* dMinutes                - Минуты (если есть)
//char* szTarif                    - Тарифный план
//DWORD dwMaxTarifLen            - Максимальная длина буффера
//char* szMessage                - сообщение об ошибке
//DWORD dwMaxMessageLen            - Максимальная длина буффера
//FN_HTTPDOWNLOAD httpDownload    - указатель на функцию (см. объявление FN_HTTPDOWNLOAD)
function GetAccountState(szAccount : PChar; szPassword : PChar; dBalance : pDouble; dOverdraft : pDouble; dActive : pDouble; dMinutes : pDouble; szTarif : PChar; dwMaxTarifLen : DWORD; dwTarifDays : pDWORD; dwTarifDaysLeft : pDWORD; szMessage : PChar; dwMaxMessageLen : DWORD; httpDownload : FN_HTTPDOWNLOAD) : BOOL; stdcall;
begin
 httpDownload(PChar('http://адрес'), PChar('POST'), PChar(Format('username=%s&password=%s', [szAccount, szPassword])), nil,
  PChar('Content-Type: application/x-www-form-urlencoded'), Фиг знает что тут, dwMaxMessageLen);
  Result := TRUE;
end;
 

 
Вот хотелось бы узнать как значение для pBuffer : pBYTE прописать в callback функции httpDownload. И правильно ли сувать dwMaxMessageLen в callback заместо dwMaxBufferLen? Понятно что это длина буфера, ну и так по описанию тоже понятно и вроде бы в pBuffer должна возвратиться вся полученная информация, которую мы и должны затем обработать как нам нужно? так это или не так? Для меня это просто ново все и хотелось бы убедиться, тем более в плагине идет работа с указателями.
 
Надо ли понимать что отпарсенный результат уже в удобочитаемом виде мы должны будем поместить, например, в переменную dBalance, которая pDouble и так далее? Если это так, скажите как привести тип String к типу pDouble (искал в яндексе/гугле, но результаты не увенчались успешным поиском). Спасибо.

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 17:59 12-08-2008
DmitryKz

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ребята, помогите разобраться. Нужно подсчитать употребление каждого слова в Вордовском документе и заполнить таблицу Парадокс, в которой три поля: WordID, Word, Count. Вторичный индекс построен по полю Word. Доступ к таблице через БДЕ.
Пример тестовый, будет нужен в дальнейшем. На форме кнопка, по нажатию которой загружается документ. Два поля редактирования: в одном - общее кол-во слов. Во втором должнен бы отображаться номер текущего слова. Ну и сетка DBGrid. Вот код:

Цитата:
procedure TForm1.btnOpenClick(Sender: TObject);
var
  Word_: variant;
  i: integer;
  tWord: string;
begin
  if not OpenDialog1.Execute then exit;
  W := CreateOleObject('Word.Application');
  W.Documents.Open(OpenDialog1.FileName);
  W.Documents.Item(OpenDialog1.FileName).Activate;
  Word_ := W.ActiveDocument.Words;
  DataModule2.words.Exclusive := true;
  DataModule2.words.Active := true;
  if not DataModule2.words.IsEmpty then DataModule2.words.EmptyTable;
  DataModule2.words.IndexName := 'Words';
  Edit1.Text := IntToStr(Word_.Count);
  DataModule2.words.DisableControls;
  for i := 1 to Word_.Count do
  begin
    tWord := Word_.Item(i);
    if tWord[1] <= ' ' then continue;
    Edit2.Text := IntToStr(i);
    if DataModule2.words.FindKey([tWord]) then begin
      DataModule2.words.Edit;
      DataModule2.words['Count'] := DataModule2.words['Count'] + 1;
      DataModule2.words.Post; end
      else begin
        DataModule2.words.Insert;
        DataModule2.words['Word'] := tWord;
        DataModule2.words['Count'] := 1; end;
  end;
  DataModule2.words.EnableControls;
 
end;

Все работает, но есть несколько проблем, которые не знаю как решить.
Во-первых, очень медленно заполняется таблица. Есть небольшой тестовый документ в сто тысяч слов. 10 тысяч обрабатывается за 10 минут - получается весь документ с учетом перестройки таблицы по индексу должен обрабатываться что-то около 2 часов. Может, есть какие-то другие технологии, более быстрые?
Во-вторых, во время заполнения таблицы форма становится "застывшей" - ее не подвигать, и, соответственно, поля редактирования не обновляются (код Edit1.Text := IntToStr(Word_.Count); Edit2.Text := IntToStr(i);. Что-то с этим можно сделать?
Извиняюсь за возможно корявый код, как уже сказал - пример тестовый

Всего записей: 3144 | Зарегистр. 29-09-2005 | Отправлено: 00:45 19-08-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
for i := 1 to Word_.Count do
  begin
    tWord := Word_.Item(i);
    if tWord[1] <= ' ' then continue;
    Edit2.Text := IntToStr(i);
   Application.ProcessMessages //добавить, чтобы форма реагировала (вроде так пишется)  
    if DataModule2.words.FindKey([tWord]) then begin
      DataModule2.words.Edit;
      DataModule2.words['Count'] := DataModule2.words['Count'] + 1;
      DataModule2.words.Post; end
      else begin
        DataModule2.words.Insert;
        DataModule2.words['Word'] := tWord;
        DataModule2.words['Count'] := 1; end;
  end;
  DataModule2.words.EnableControls;  

 
далее, попробуй считать документ ворда (или слова) в память - ускорение в разы будет.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 04:41 19-08-2008
shulum



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Во-вторых, во время заполнения таблицы форма становится "застывшей" - ее не подвигать, и, соответственно, поля редактирования не обновляются (код Edit1.Text := IntToStr(Word_.Count); Edit2.Text := IntToStr(i);. Что-то с этим можно сделать?

Загнать в отдельный поток ... если лень возиться с созданием оного самостоятельно, то можно просто воспользоваться компонентом из комплекта JVCL (TJvThread), либо внутри цикла обновлять эти компоненты ... Edit1.refresh

Всего записей: 121 | Зарегистр. 11-06-2006 | Отправлено: 10:34 19-08-2008
DmitryKz

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
Спасибо, а можно уточнить, что значит считать документ ворд в память? Доступ к нему через COM.

Всего записей: 3144 | Зарегистр. 29-09-2005 | Отправлено: 10:42 19-08-2008 | Исправлено: DmitryKz, 11:04 19-08-2008
lerthe61

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Во-первых, очень медленно заполняется таблица. Есть небольшой тестовый документ в сто тысяч слов. 10 тысяч обрабатывается за 10 минут - получается весь документ с учетом перестройки таблицы по индексу должен обрабатываться что-то около 2 часов. Может, есть какие-то другие технологии, более быстрые?

Почему бы вам не воспользоваться профайлером?

Всего записей: 74 | Зарегистр. 04-05-2007 | Отправлено: 11:28 19-08-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
DmitryKz

Цитата:
Ребята, помогите разобраться. Нужно подсчитать употребление каждого слова в Вордовском документе и заполнить таблицу Парадокс, в которой три поля: WordID, Word, Count.  

Это принципиально, чтобы парадокс таблица была? Просто ИМХО проще было бы сделать акцезовскую таблицу, туда скинуть ВСЕ слова (да да, именно все), а потом уже в грид грузануть что нить типа такого  
select Word,Count(Word) from MyTable group by Word
то есть по идее должно будет вывестись уникальное слово и рядом с ним счетчик в таблице.  
 
О другая идея. Создаешь динамический массив, наподобие твоей базы (работа с памятью шустрей чем с базой ИМХО). Туда скидываешь свои слова и сколько уже найдено, по массиву бегаешь в поисках слов (заодно увеличивая значения). а потом уже скидываешь массив в базу

Цитата:
      DataModule2.words.Edit;
      DataModule2.words['Count'] := DataModule2.words['Count'] + 1;
      DataModule2.words.Post; end
 

так лучше не надо (фигова туча обращений на открытие закрытие.
Лучше один раз вверху едит, а потом после окончания обработки текста пост. Хотя я Парадоксом не работал давно, но думаю ускорение должно быть.
И еще попробуй отследить слабое место, вначале прогони документик без записи в базу.ю чтобы опредилть, что именно тормозит - поиск по документу или запись в базу.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 12:18 19-08-2008
DmitryKz

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
О другая идея. Создаешь динамический массив

Угу, я уже испытал эту идею. Сразу обнаружилось слабое место - обращение к документу через COM - заполнение массива идет так же медленно, как заполнение базы напрямую. Просто если цикл прогнать с отображением итерации цикла в Эдите - десяток (даже меньше) секунд. Получается, надо получать готовый текст сразу и затем парсить на отдельные слова? Тут, кстати, другая еще проблема обозначилась - мне нужен Юникодный текст (в документе греческие и иврит слова). Как его выцепить?

Всего записей: 3144 | Зарегистр. 29-09-2005 | Отправлено: 13:05 19-08-2008
anfilat

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
DmitryKz

Цитата:
Тут, кстати, другая еще проблема обозначилась - мне нужен Юникодный текст (в документе греческие и иврит слова). Как его выцепить?

Вообщето COM только с юникодом работает. Поэтому замени tWord: string; на tWord: WideString; и будет тебе счастье

Цитата:
Сразу обнаружилось слабое место - обращение к документу через COM  

А ты не через IDispatch работай, а через IUnknown - будет быстрее. В Delphi для этого готовый компонент должен быть, на вкладке ActiveX кажется

Всего записей: 845 | Зарегистр. 12-08-2005 | Отправлено: 13:36 19-08-2008
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
DmitryKz
Формат doc принципиален? Есть ли вариант сохранить в rtf, а его уже потом грузить в скрытый контрол и с ним уже работать?

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 15:33 19-08-2008
greeng

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
вообщим написал приложение для работы с таблицами DBF формата  
есть файл настроек dat.ini откуда берется номер компа(участка) и путь к базам и файлу PDOXUSRS.NET
далее при открытии таблицы она вилтруется по номер компа(участка) , тоесть при одновременном открытии несколькими пользователями с разными настройками участков в файле dat.ini каждый будет видить только свои записи.
 
вопрос!
 
все будет нормально работать не будут ли косяков при редактировании и сохранении таблиц?
 
если нет то предложите плиз свои варианты.
С Уважением ко всем Григорий.




не надо кросспостить. Спросил в одном месте, не надо в другом спрашивать.

Всего записей: 6 | Зарегистр. 05-06-2008 | Отправлено: 16:48 19-08-2008 | Исправлено: ShIvADeSt, 02:17 20-08-2008
V1s1ter



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
greeng
При работе по сети через BDE могут проити глюки. Я боролся с ними почти два года, в конце концов переделал все базы под AbsoluteDataBase (В нем есть конверитилка и переделка программы заняла около одного дня, а программа здоровая и таблиц 486 штук). Я это написал ести ты планируеш разработку новой программы/базы. Если же в наследство осталиь DBF файлы+другие работающие с ними программы, порекомендую следующее.  
Вариант 1. Работай с компонентами TQuery и TSQL, не используй TTable, работа через этот компонент в условиях сети приводила к потере данных.  
Вариант 2. Работай с компонентами типа TMemoryTable. Получаеш свои записи на локальную машины, работаеш с ними и в пакетном режиме записываеш назад в базу.
Вариант 3. Оставь как написал, при небольшом трафике и отсутствии BLOB-полей  все должно работать.  
 
С BDE я мучался долго и сам прописывал и настройки и специалисты мне помогали и "специалисты" мне тоже советовали - результат в первых строках...

Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 17:56 19-08-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вобщем, разобрался с этим модулем. И еще хотел узнать, может кто-то делал функцию для извлечения подстроки?
Мой вариант таков:

Код:
 
function ExtractSubString(Source, First, Second : String) : String;
var
  S : String;
  T : String;
  P : Integer;
begin
  S := Source;
  // находим символ, с которого начинается первая искомая строка
  P := Pos(First, Source);
  // начинаем удалять с первой позиции число символов + число символов,
  // котороое мы подсчитали длиной первой искомой строки
  Delete(S, 1, P - 1 + Length(First));
  // получаем требуемую извлеченную строку для дальнейшей обработки
  // находим символ, с которого начинается вторая искомая строка
  P := Pos(Second, S);
  // скопируем временно строку с полученной позиции для подсчета ее длины
  T := Copy(S, P, Length(S));
  // начинаем удалять с первой позиции число символов + число символов,
  // котороое мы подсчитали длиной второй искомой строки
  Delete(S, Length(S) - Length(T) + 1, Length(T));
  // возвращаем нужный нам результат в виде подстроки
  Result := S;
end;
 

Может есть более лучшее решение? Ну или хотя бы пооптимизированней?
 
И еще хотел поинтересоваться. У кого-нибудь есть nonvcl функция FormatFloat? Ну или ее аналог для форматирования строки. То есть подаем в функцию например с маской ##.## число 12345, а получаем 12.34. Требуется для подсчета денежной суммы.

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 02:46 20-08-2008
Jokerjar79



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Maks150988, на счет первого вопроса: не нужна переменная S, можно работать прям с Source - функция не изменит поданную переменную, т.к. она копируется в стек. Ну и в конце малость лишнего. В общем, можно сделать так:
 

Код:
function ExtractSubString(Source, First, Second: string): string;
var
  i1, i2: integer;
begin
  i1 := pos(First, Source) + length(First);
  delete(Source, 1, i1 - 1);
  i2 := pos(Second, Source) - 1;
  result := copy(Source, 1, i2);
end;

 
На счет FormatFloat. Если та, о которой я думаю, то она и так не vcl, находится в SysUtils

Всего записей: 710 | Зарегистр. 08-09-2007 | Отправлено: 05:38 20-08-2008 | Исправлено: Jokerjar79, 05:44 20-08-2008
Maks150988



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Jokerjar79
Спасибо за функцию.
Вас не затруднит выцепить из модуля SysUtils FormatFloat функцию? Якак всегда поторопился и поставил урезанно Delphi и pas файлов нет. А диск опять куда-то подевал. У меня есть модуль Lenin_SysUtils, но чего-то не пойму. Компилятор выдает ошибки. Там указано как:
 

Код:
 
{$L Lenin_Ffmt.obj}
 
function FloatToTextFmt(Buffer: PChar; const Value;ValueType: TFloatValue;
  Format: PChar): Integer;
begin end;
 
function FormatFloat(const Format: string; Value: Extended): string;
var
 Buffer: array[0..255] of Char;
begin
 SetString(Result, Buffer, FloatToTextFmt(Buffer, Value, fvExtended, PChar(Format)));
end;
 

 
На const Value выдает фигню какую-то. Ставил Extended по смыслу как в эту переменную подают такого же типа значение, программа работает, но вываливается.
Уж не знаю что не так в Lenin_Ffmt.obj, но компилятор 7 Делфи пишет:
 
[Warning] MSysUtils.pas(90): Return value of function 'FloatToTextFmt' might be undefined
[Warning] MSysUtils.pas(217): Bad global symbol definition: 'FLOATTOTEXTFMT' in object file 'Lenin_Ffmt.obj'
[Error] MSysUtils.pas(247): Unsatisfied forward or external declaration: 'CURRENCYSTRING'
[Error] MSysUtils.pas(247): Unsatisfied forward or external declaration: 'CURRENCYFORMAT'
[Error] MSysUtils.pas(247): Unsatisfied forward or external declaration: 'NEGCURRFORMAT'
[Error] MSysUtils.pas(247): Unsatisfied forward or external declaration: 'THOUSANDSEPARATOR'
[Error] MSysUtils.pas(247): Unsatisfied forward or external declaration: 'DECIMALSEPARATOR'

Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 08:58 20-08-2008
   

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (все версии) - часть 4
ShIvADeSt (28-06-2009 02:10): Продолжение в http://forum.ru-board.com/topic.cgi?forum=33&topic=10477


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru