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

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

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

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

Открыть новую тему     Написать ответ в эту тему

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Продолжение темы Вопросы по Delphi (до версии 2009) - часть 5

Познаем сами, помогаем другим...
Обсуждаем вопросы, не связанные с юникоидными версиями Delphi - для этого есть соответствующая тема (см. ссылки ниже).


 
Правила топика:
    Прежде чем спрашивать:
  1. Желательно изучить вопрос, попытаться найти ответ в прилагаемых мануалах, хелпах и анализируя исходники.
  2. Выполнить поиск по топику (открыть "Версия для печати" и поискать ответ там).
  3. Применить фильтр по разделу "Прикладное программирование". Ответы на многие старые вопросы могли быть даны в отдельных темах.
  4. Продумайте вопрос. На поверхностные вопросы вы получите поверхностные ответы, или вообще ответов не получите.
  5. Желательно указывать версии используемого компилятора и операционной системы.
    Прежде чем отвечать:
  1. Если не можете помочь, не мешайте.
  2. Если уж вы отвечаете на вопрос, давайте ответ по сути.
  3. Если вы не уверены, так и говорите! Ошибочный, но авторитетно звучащий ответ хуже, чем отсутствие ответа.
  4. Задавайте дополнительные вопросы, чтобы получить больше информации.
  • Отсутствие ответа не равносильно игнорированию - иногда участники форума просто не знают ответ. Повторная посылка вопроса не приветствуется. Посты типа "неужели никто не знает ответа..." или "может мне все-таки кто-нибудь ответит" недопустимы.  
  • Все большие куски кода (более 5 строк) оформляем в тег [morе] дабы уменьшить размер поста. FAQ по тегу [morе].


    Некоторые "родственные" топики:
     
  • Вопросы по Delphi (версии 2009-2010 Weaver)
  • Вопросы по компонентам для Delphi, C++ Builder
  • Использование DevExpress
  • Вопросы по Ehlib
  • Компоненты и утилиты для Delphi/BCB/FreePascal/Lazarus - только Open Source
  • Коммерческие компоненты и утилиты для Delphi/BCB
  • кабак программистов :)
     
    См. также: Некоторые полезные ресурсы о Delphi
     
    И старайтесь, чтобы ваш код не попал сюда :)

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 05:13 19-05-2010 | Исправлено: akaGM, 02:33 15-07-2020
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Доброго времени суток. Пишу приложение с плагинами. Собственно выскакивает AV.
     
    Код плагина:
     

    Код:
    library Plugin;
     
    uses
      Windows, SysUtils;
     
    type
      PPLUGIN_TEST = ^PLUGIN_TEST;
      PLUGIN_TEST = record
        test: DWORD;
      end;
     
    function PluginInit(var pt: PLUGIN_TEST): BOOL; stdcall;
    begin
      MessageBox(GetActiveWindow, LPCSTR('Hello From PlugIn!'), nil, MB_ICONSTOP);
      Result := TRUE;
      pt.test := 777;
      MessageBox(GetActiveWindow, LPCSTR(IntToStr(pt.test)), nil, MB_ICONSTOP);
    end;
     
    exports
      PluginInit index 1;
       
    begin
    end.

     
    В самом приложении вызываю так:
     

    Код:
    type
      TPluginInit = function(var pt: PLUGIN_TEST): BOOL; stdcall;
    var
      init: TPluginInit;
      pt: PLUGIN_TEST
    begin
      init := GetProcAddress(hInst, LPCSTR('PluginInit'));
      ZeroMemory(@pt, SizeOf(PLUGIN_TEST));
       init(pt);
      MessageBoxW(GetActiveWindow, LPWSTR(IntToStrW(pt.test)), nil, MB_OK);
    end;

     
    MessageBox с текстом Hello отображается - значит правильно все вызываю. Проблема в заполнении структуры PLUGIN_TEST. Вот с этим хотелось бы разобраться. Крутил вертел по всякому и указатель PPLUGIN_TEST ставил в код плагина и результат тот же.

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 19:37 20-01-2012 | Исправлено: Maks150988, 20:21 20-01-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    В клиентском приложении PLUGIN_TEST какое определение имеет?  
    Вообще создается впечатление, что вы для выкладки на форуме очень щедро и невнимательно как-то сократили код. Например ваш клиентский код приложения где вообще написан? В модеуле .dpr?
     
    Добавлено:
    delover
    Попробуйте перенести CoInitialize/CoUninitialize из секций инициализации в область видимости ole-переменной. Типа такого  

    Код:
     
    procedure DoSmth
    begin
      ...
      CoInitialize;
      try  
        oOle := CreateOle;
         ....
      finally
        CoUninitialize;
      end;
    end;
     

    Звучит быть может странно, но несколько раз уже помогало.

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 21:09 20-01-2012
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
    Попробуйте packed record. Вполне возможно, что дело в выравнивании.

    Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 21:44 20-01-2012
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    wasilissk
    В клиентском приложении структуры те же, что и в модуле. =) Я вот только не понял, а зачем CoInitialize/CoUninitialize функции. Я же OLE не использую. =)
    Frodo_Torbins
    Блин, неожиданно помогло. =)

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 15:38 21-01-2012
    wasilissk

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

    Цитата:
    Я вот только не понял,

    Это не к вам было обращено, я же ник там указал к кому обращаюсь.

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 14:26 22-01-2012
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    wasilissk
    Извиняюсь, совсем погряз в коде программы, что уже не замечаю таких очевидностей. =))

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 03:42 23-01-2012
    delover

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    wasilissk
    Попробовал тру финали, очень жаль что не помогло. Выяснилась особенность немного странная, на некоторых компах закрывается корректно. Просто программа умеет работать ещё и с другими драйверами и возможно где эти драйвера не установлены там она и работает корректно. А вот потом я даже убрал CoInitialize, мой драйвер работает корректно, но так же подвисает прога. Дело не в CoInitialize.

    Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 09:23 25-01-2012
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    А кто подскажет насчет правильного написания кода к условию.
     

    Код:
        if (pcp.bHover and pcp.bPressed) then
        begin
          clrTop  := RGB($D3, $F9, $FF);
          clrBott := RGB($E0, $EF, $FF);
        end
        else
        if (pcp.bHover and (not pcp.bPressed)) then
        begin
          clrTop  := RGB($D2, $E8, $FE);
          clrBott := RGB($C3, $D8, $EC);
        end
        else
        if ((not pcp.bHover) and pcp.bPressed) then
        begin
          clrTop  := RGB($D2, $E8, $FE);
          clrBott := RGB($C3, $D8, $EC);
        end;
        if (pcp.bHover or pcp.bPressed) then
          GradFillRect(pcp.hdcMem, pcp.rcClient, clrTop, clrBott, GRADIENT_FILL_RECT_V);

     
    Компилятор предупреждает что переменные не инициализируются. Но в условии (pcp.bHover or pcp.bPressed) они уже должны быть инициализированы и GradFillRect нарисует фон согласно нужным значениям. Так-то понятно что можно еще добавить else и там присвоить например этим значениям нули.

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 13:15 29-01-2012
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
    Компилятор волнуется, что возможна ситуация, когда pcp.bHover и pcp.bPressed false. Как вариант: уберите последний if ((not pcp.bHover... оставив только его begin/end.

    Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 15:25 29-01-2012
    salexn1



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
    либо как вариант изначально инициализируй переменные.

    Всего записей: 502 | Зарегистр. 21-02-2008 | Отправлено: 12:37 30-01-2012
    idiMAN

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
    Твой код можно переписать так (если конечно в случае pcp.bHover=false и pcp.bPressed=false у тебя не предусмотрен другой цвет):

    Код:
     
    clrTop  := RGB($D2, $E8, $FE);  
    clrBott := RGB($C3, $D8, $EC);
     
    if (pcp.bHover and pcp.bPressed) then  
    begin  
       clrTop  := RGB($D3, $F9, $FF);  
       clrBott := RGB($E0, $EF, $FF);  
    end;
     
    if (pcp.bHover or pcp.bPressed) then  
          GradFillRect(pcp.hdcMem, pcp.rcClient, clrTop, clrBott, GRADIENT_FILL_RECT_V);  
     


    Всего записей: 466 | Зарегистр. 05-05-2003 | Отправлено: 11:20 01-02-2012
    Ichigo2



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Послали к вам.
    Я хочу чтобы моя программа проверяла свою контрольную сумму. Есть процедура MD5File, но если подсунуть ей уже запущенную программу, то будет ошибка. Как правильно это реализовать?

    Всего записей: 153 | Зарегистр. 01-05-2011 | Отправлено: 15:52 01-02-2012
    wasilissk

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Ichigo2
    Использовать процедуру MD5FileEx, которая не вызывает ошибок.

    Всего записей: 293 | Зарегистр. 25-12-2006 | Отправлено: 16:12 01-02-2012
    ant0ni02004

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

    Цитата:
    либо как вариант изначально инициализируй переменные

     
    пару раз хохма случалась, когда после начального присваивания
    начиналось "value assigned to ... never used", а без него "переменные не инициализируются"

    Всего записей: 442 | Зарегистр. 26-10-2004 | Отправлено: 18:43 01-02-2012
    HekTo

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

    Всего записей: 186 | Зарегистр. 30-09-2003 | Отправлено: 12:11 02-02-2012 | Исправлено: HekTo, 12:16 02-02-2012
    king_stiven

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Собственно моя задача - это посылать в окно bat файла нажатия клавиш, причём окно может быть свёрнутым или скрытым, нашёл вот такую штуку:
    http://sources.ru/delphi/delphi_send_keystrokes.shtml

    Код:
     
     
    Посылаем нажатия клавиш другому приложению.
     
    Автор: Gert v.d. Venis
     
    Скачайте компонент Sendkeys
    http://sources.ru/delphi/sendkeys.zip
     
     
    Описание:
    Данный компонент получает хэндл(handle) любого запущенного окна и даёт возможность отправить по указанному хэндлу любые комбинации нажатия клавиш.
     
    Совместимость: Все версии Delphi
     
     Собственно сам исходничек:
     
    После того, как проинсталируете этот компонент, создайте новое приложение и поместите на форму кнопку и сам компонент SendKeys. Добавьте следующий код в обработчик события OnClick кнопки:
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      // Запускаем Notepad, и ему мы будем посылать нажатия клавиш
      WinExec('NotePad.exe', SW_SHOW);
      // В параметре процедуры GetWindowHandle помещаем
      // текст заголовка окна Notepad'а.
      SendKeys1.GetWindowHandle('Untitled - Notepad');
      // Если хэндл окна получен успешно, то отправляем ему текст
      if SendKeys1.WindowHandle <> 0 then
        SendKeys1.SendKeys('This is a test');
      // Так же можно отправить код любой кнопки типа
      // RETURN, используя следующий код:
      // SendKeys1.SendKeys(Chr(13));
    end;  
     
     

     
    Так вот, скачал я этот sendkeys.zip, там внутри файлы:
    SendKeys.dcr
    SendKeys.pas
    sendkeys.upl
     
    И теперь прошу ткнуть меня, что делать дальше ибо кроме батников я ничего не понимаю, хотя и гложут меня смутные сомнения, что нужно качнуть компилятор(какой?) и произвести некоторые действия(какие?) и что я получу в результате, exe файл?

    Всего записей: 2229 | Зарегистр. 17-07-2006 | Отправлено: 21:31 03-02-2012 | Исправлено: king_stiven, 21:39 03-02-2012
    Ichigo2



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Чем отличается подключение модулей в секции interface от подключения их в секции implementation?

    Всего записей: 153 | Зарегистр. 01-05-2011 | Отправлено: 23:45 03-02-2012 | Исправлено: Ichigo2, 23:46 03-02-2012
    Frodo_Torbins

    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    king_stiven
    Если кроме батников ничего не понимаете, то может вам поможет xStarter или HiAsm?
    Что касается компиляторов, то вам нужно скачать отсюда и установить Delphi7. Потом либо скачать отсюда DRKB 3.0 и прочитать там про имитацию нажатий клавиш без всяких сторонних компонентов, либо прочитать про установку компонент без dpk-файлов. Даже и не знаю что легче.
     
    Ichigo2
    У каждого модуля могуть быть секции инициализации (initialization) и финализации (finalization). Они выполняются в самом начале и самом конце работы приложения. Обычно туда вставляют код, необходимый для нормальной работы модуля. Так вот секции инициализации всех модулей из раздела interface гарантированно выполнятся до начала работы секции инициализации вашего модуля. Таким образом вы можете спокойно вызывать из них любой код. Для модулей из раздела implementation никаких гарантий нету, поэтому их код нельзя использовать в своей секции инициализации.

    Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 00:01 04-02-2012 | Исправлено: Frodo_Torbins, 00:10 04-02-2012
    ESV1987

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Здравствуйте!
     
    Давно пишу простенькие проги на Делфи, читал много руководств, но с некоторыми (кажется, очень простыми) вещами до сих пор от случая к случаю возникают проблемы.
     
    Сейчас вот, к примеру, мучают динамические массивы. Без них не удаётся добиться универсальности создаваемых подпрограмм.
     
    1. Передача динамического массива на вход процедуры и соответственно выдача на выходе другого динамического массива.
     
    На фортране это дело решается элементарно, на вход идёт просто переменная, а в секции описания она описана, как dimension :: XYZ (Ndim) (......). В делфи же создаю я тип type DynAr = array of extended или даже array of array of extended, переменная на входе и выходе процедуры описывается этим типом.
     
    Так вот, при передаче массива в процедуру из юнита, где эта процедура находится и из внешнего юнита часто у меня происходит путаница... то сбивается указатель и массив вместо требуемых значений указывает на какую-то белиберду в другой части памяти, либо ещё что-то (var перед именем массива на входе часто как-то неадекватно на него действует и т.п.).  
     
    Не могли бы вы раз и навсегда мне разъяснить, как мне заслать динамический массив на вход процедуры и внутри процедуры его адекватно обработать, затем выдав другой массив на выходе? Где надо передать указатели и т.п.?
     
    2. Запись большого кол-ва информации в динамический массив.  
     
    Так необходимо в программе, чтобы раз в N шагов сохранялась информация в динамический массив. И если шаг очень маленький, то даже на интервале средней длины, часто динамические массивы "переполняются".
    Можно ли как-то их описать по особому, чтобы переполнений не было, может не стандартный класс использовать, а библиотеку какую-нибудь.
     
    Мне однажды предложили писать в поток (Stream), но из него неудобно потом считывать. Через анализ содержания не найти нужную строку, приходится запоминать шаги (для считывания по числу байт), что не подходит мне в данном случае.
     
    3. Как узнать все размерности многомерного массива? к примеру у меня массив двумерный, length выдаёт только одну границу, а как узнать вторую? (кроме использования библиотек, где под динамические массивы создан класс, хранящий свойства размерностей, естественно)
     
    Ну вот пока всё, хотя вопросов тьма.
     
    Казалось бы, тема динамических массивов должна быть один раз хорошо освещена в учебниках и всё. А я сколько их не читал, чётких ответов на эти вопросы так и не нашёл. В DRKB предлагают свой класс массивов, но это не всегда удобно..

    Всего записей: 56 | Зарегистр. 31-03-2007 | Отправлено: 00:39 04-02-2012 | Исправлено: ESV1987, 00:52 04-02-2012
    akaGM

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

    Цитата:
    Не могли бы вы раз и навсегда мне разъяснить, как мне заслать динамический массив на вход процедуры и внутри процедуры его адекватно обработать, затем выдав другой массив на выходе? Где надо передать указатели и т.п.?
    например, вот так:
    Код:
     
    const
      N = 5;
    var
      x, y: array of double;
      i: integer;
     
    procedure calc1(N: integer; var x, y: array of double);
    var
      i: integer;
    begin
      for i := 0 to N-1 do
        y[i] := 10*x[i];
    end;
     
    //можно и не передавать размерность и воспользоваться псевдофункциями Low/High
    procedure calc2(var x, y: array of double);
    var
      i: integer;
    begin
      for i := Low(x) to High(x) do
        y[i] := 100*x[i];
    end;
     
     
    begin
    //это выделение памяти для x y
      setlength(x, N);
      setlength(y, N);
     
      for i := 0 to N-1 do
        x[i] := i+1;
     
      calc1(N, x, y);
      for i := 0 to N-1 do
        writeln(i:3, '  ', y[i]);
     
      calc2(x, y);
      for i := Low(y) to High(y) do
        writeln(i:3, '  ', y[i]);
     
    end.


    Цитата:
    Так необходимо в программе, чтобы раз в N шагов сохранялась информация в динамический массив. И если шаг очень маленький, то даже на интервале средней длины, часто динамические массивы "переполняются".
    Можно ли как-то их описать по особому, чтобы переполнений не было, может не стандартный класс использовать, а библиотеку какую-нибудь.

    функцией setlenght() выделяют память для
      x: array of double;
      setlenght(x, 10)
     
    но её же можно использовать и для перераспределения
     
    если ты в программе следишь и видишь, что, скажем, размер массива стремится к критическому, то поможет след. пример:
     
      setlength(x, 10); // место для 10 даблов
      writeln('size(x)= ', length(x));
     
      setlength(x, 20); // уже для 20, добавили ещё 10 дабло-мест...
      writeln('size(x)= ', length(x));

    Всего записей: 24056 | Зарегистр. 06-12-2002 | Отправлено: 01:49 04-02-2012 | Исправлено: akaGM, 01:55 04-02-2012
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 6


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

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

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru