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

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в 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
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Frodo_Torbins
    А что вы можете предложить? Хотя бы подкиньте ссылочек на использование подобных массивов. А то вечно с ShortString хрень попадается.

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 09:17 18-08-2012
    A_V

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
    UpdateArrayItem можно написать через:
     
        FreeArrayItem(DynArray[idItemIndex]);
        CopyArrayItem(tmpInfo, InfoEx);
        DynArray[idItemIndex] := tmpInfo;

    Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 13:51 18-08-2012
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Frodo_Torbins
    A_V
     
    Да вот хотел на простом примере проконсультироваться тут. Не все так просто. Вот рекорд и функции из моего проекта.
     
    Дальше
     
    Функция UpdateArrayItem с закомментированным кодом не отрабатывает как положено. Почему-то в указателях появляется мусор в конце. Вот и удаляю я элемент в списке и заного его добавляю. Хочется просто тупо сделать аналог сообщения, например, LVM_INSERTITEM, где заполняем структуру и контрол сам копирует себе то что нужно и орудует выделенными буферами с текстом. А дальше я достаю инфу из этого массива и отображаю пользователю...

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 21:56 18-08-2012 | Исправлено: Maks150988, 22:00 18-08-2012
    A_V

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

    Цитата:
    Почему-то в указателях появляется мусор в конце

    значит где-то строка не завершается с #0#0. приведи полный пример с ошибкой.
     
    вообще, если все это внутри твоего приложения, то чем дельфевые строки не устроили?

    Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 20:16 19-08-2012
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    A_V
    Строки Delphi не устроили тем, что впоследствии я расчитывал на использование плагинов, написанных на других языках. Приложение у меня поддерживает полностью Юникод, вроде как можно было напрямую WideString передавать, но я хотел еще сделать Ansi варинат для устаревших систем. Так что потом можно было легко поменять PWideChar на PAnsiChar.
     
    Вобщем так, кода многовато, поехали... Будем считать, что у меня уже запущена программа и массив pAccountData (TAccountInfoExArr это Array of ACCOUNT_INFO_EX) заполнен необходимыми значениями. Для манипуляции с массивом используется тот код функций из предыдущего сообщения.
     
    Для примера обновим 3 элемент массива значениями из структурки ptrInfo. Эту структуру заполняет функция UpdateItemInfo, в которую плагин передает некоторые значения. Если UpdateItemInfo вернула True, значит обновим столбцы и строки ListView и обновим элемент в массиве pAccountData.
     
    var
        bRet    : Boolean;
        ptrInfo : ACCOUNT_INFO_EX;
    begin
          bRet := UpdateItemInfo(3, ptrInfo);
          if bRet then
          begin
            UpdateListItem(hListView, 3, ptrInfo);
            UpdateArrayItem(pAccountData, 3, ptrInfo);
          end;
    end;

     
    Сам код функции UpdateListItem приводить не буду полностью. Он грубо говоря примерно такой. Вобщем здесь ошибок уж точно не должно быть...
     
             ZeroMemory(@lvi, SizeOf(TLVItemW));
              lvi.mask     := LVIF_TEXT;
              lvi.iItem    := nDestItem;
              lvi.iSubItem := IdItem;
              lvi.pszText  := ptrInfo.pszAccount;
              SendMessageW(hListView, LVM_SETITEMW, 0, Integer(@lvi));

     
    Код функции UpdateArrayItem в предыдущем сообщении. Приведу лучше код функций UpdateItemInfo (заполняет инфой от плагина заветную структуру). Может и тут косячок...
     
    function UpdateItemInfo(const IdItem: Integer; var ptrInfo: ACCOUNT_INFO_EX): Boolean;
    var
      dwInfoIndex: Integer;
      ai         : ACCOUNT_INFO;
      exec       : TPluginExecute;
      st         : TSystemTime;
      pszText    : WideString;
    begin
      Result := FALSE;
      ZeroMemory(@ai, SizeOf(ACCOUNT_INFO));
      ai.pszLogin        := pAccountData[IdItem].pszLogin;
      ai.pszPassword     := pAccountData[IdItem].pszPassword;
      ai.cchPasswordMax  := pAccountData[IdItem].cchPasswordMax;
      ai.fBalance        := pAccountData[IdItem].fBalance;
      ai.fOverdraft      := pAccountData[IdItem].fOverdraft;
      ai.pszTarif        := pAccountData[IdItem].pszTarif;
      ai.cchTarifMax     := pAccountData[IdItem].cchTarifMax;
      ai.dwTarifDays     := pAccountData[IdItem].dwTarifDays;
      ai.dwTarifDaysLeft := pAccountData[IdItem].dwTarifDaysLeft;
      ai.dwErrorCode     := pAccountData[IdItem].dwErrorCode;
      ai.pszError        := pAccountData[IdItem].pszError;
      ai.cchErrorMax     := pAccountData[IdItem].cchErrorMax;
      dwInfoIndex := pAccountData[IdItem].dwEqualIndex;
      if (dwInfoIndex <> -1) then
      begin
        exec := pPluginData[dwInfoIndex].exec;
        Result := exec(ai);
      end;
      if Result then
      begin
        GetLocalTime(st);
        pszText := FormatUpdateTimeDateW(st);
        ptrInfo.bUpdateState   := pAccountData[IdItem].bUpdateState;
        ptrInfo.clsid          := pAccountData[IdItem].clsid;
        ptrInfo.dwEqualIndex   := pAccountData[IdItem].dwEqualIndex;
        ptrInfo.pszAccount     := pAccountData[IdItem].pszAccount;
        ptrInfo.cchAccountMax  := pAccountData[IdItem].cchAccountMax;
        ptrInfo.pszLogin       := pAccountData[IdItem].pszLogin;
        ptrInfo.cchLoginMax    := pAccountData[IdItem].cchLoginMax;
        ptrInfo.pszPassword    := pAccountData[IdItem].pszPassword;
        ptrInfo.cchPasswordMax := pAccountData[IdItem].cchPasswordMax;
        ptrInfo.fBalance       := ai.fBalance;
        ptrInfo.fOverdraft     := ai.fOverdraft;
        ptrInfo.pszTarif       := ai.pszTarif;
        ptrInfo.cchTarifMax    := ai.cchTarifMax;
        ptrInfo.pszUpdated     := LPWSTR(pszText);
        ptrInfo.cchUpdatedMax  := (lstrlenW(ptrInfo.pszUpdated) + 1) * SizeOf(WideChar);
        ptrInfo.dwTarifDays    := ai.dwTarifDays;
        ptrInfo.dwTarifDaysLeft:= ai.dwTarifDaysLeft;
        ptrInfo.dwErrorCode    := ai.dwErrorCode;
        ptrInfo.pszError       := ai.pszError;
        ptrInfo.cchErrorMax    := ai.cchErrorMax;
        ptrInfo.bYellowAlert   := pAccountData[IdItem].bYellowAlert;
        ptrInfo.fYellowAlert   := pAccountData[IdItem].fYellowAlert;
        ptrInfo.bRedAlert      := pAccountData[IdItem].bRedAlert;
        ptrInfo.fRedAlert      := pAccountData[IdItem].fRedAlert;
      end;
    end;

     
    Тут собственно просто. Заполняем структуру ACCOUNT_INFO (не ACCOUNT_INFO_EX!) данными из текущей ACCOUNT_INFO_EX (ну нужен логин и пароль просто) и подаем ее в функцию PluginExecute. Она выдает данные и мы присваиваем их в структуре ptrInfo.
     
    Ну а вот и сама родимая PluginExecute из плагина...
     
    function PluginExecute(out ai: ACCOUNT_INFO): BOOL; stdcall;
    type
      TBillingInfo = record
        errorCode   : Integer;
        msgError    : LPWSTR;
        balanceMoney: Double;
        balanceDraft: Double;
        tarifName   : LPWSTR;
        tarifDays   : Integer;
        daysLeft    : Integer;
      end;
    const
      pszTarif: LPWSTR = 'Обычный тарифный план';
      pszError: LPWSTR = 'Ошибок не обнаружено';
    var
      binfo: TBillingInfo;
    begin
      ZeroMemory(@binfo, SizeOf(TBillingInfo));
      binfo.errorCode   := NO_ERROR;
      binfo.msgError    := pszError;
      binfo.balanceMoney:= 250.00;
      binfo.balanceDraft:= 30.00;
      binfo.tarifName   := pszTarif;
      binfo.tarifDays   := -1;
      binfo.daysLeft    := -1;
      ai.fBalance        := binfo.balanceMoney;
      ai.fOverdraft      := binfo.balanceDraft;
      ai.pszTarif        := binfo.tarifName;
      ai.cchTarifMax     := (lstrlenW(ai.pszTarif) + 1) * SizeOf(WideChar);
      ai.dwTarifDays     := binfo.tarifDays;
      ai.dwTarifDaysLeft := binfo.daysLeft;
      ai.dwErrorCode     := binfo.errorCode;
      ai.pszError        := binfo.msgError;
      ai.cchErrorMax     := (lstrlenW(ai.pszError) + 1) * SizeOf(WideChar);
      Result := TRUE;
    end;

     
    Вобщем-то у меня попутно вопрос. Может теряются указатели после UpdateListItem перед UpdateArrayItem? Или данные в ptrInfo становятся невалидными...

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 21:40 19-08-2012 | Исправлено: Maks150988, 21:43 19-08-2012
    A_V

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

    Цитата:
    ptrInfo.pszPassword    := pAccountData[IdItem].pszPassword;

    не удивительно, что потом вылезают проблемы.. ты уверен, что нужно копировать указатели, а не строки?
     
    еще,

    Цитата:
    ai.cchTarifMax     := (lstrlenW(ai.pszTarif) + 1) * SizeOf(WideChar)

    если это потом используется для работы с юникдными api-ф-иями, умножать на 2 не нужно.

    Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 23:57 19-08-2012
    Frodo_Torbins

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

    Цитата:
    Строки Delphi не устроили тем, что впоследствии я рассчитывал на использование плагинов, написанных на других языках. Приложение у меня поддерживает полностью Юникод, вроде как можно было напрямую WideString передавать, но я хотел еще сделать Ansi вариант для устаревших систем. Так что потом можно было легко поменять PWideChar на PAnsiChar.  
    Чтобы легко прекомпилировать в анси вариант, нужно было свой тип вводить наподобие такого "type MyChar = WideChar;" и уже далее всюду его использовать. Но вообще реальная польза от всей этой возни с указателями весьма сомнительна. Я бы избавлялся от них как только данные поступили от плагина (в UpdateItemInfo). И внутри уже всюду использовал бы нормальные строки. Или вообще забил на анси версию, и повсеместно использовал бы WideString.

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



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

    Цитата:
    не удивительно, что потом вылезают проблемы.. ты уверен, что нужно копировать указатели, а не строки?  

    Да я вот только сейчас понял про присваивание указателей. Почему-то казалось что после заполнения ptrInfo текст сохранится. А тут получается я уже обновляю текущий элемент массива из которого я текст "сохранял".
     

    Цитата:
    если это потом используется для работы с юникдными api-ф-иями, умножать на 2 не нужно.

    Почему не нужно?
     

    Цитата:
    Я бы избавлялся от них как только данные поступили от плагина (в UpdateItemInfo)

    Каким образом?

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

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

    Цитата:
    Почему не нужно?

    Потому что обычно  ф-ии (lstrcpyn) принимают кол-во символов, а не размер в байтах

    Цитата:
    Цитата:
    Я бы избавлялся от них как только данные поступили от плагина (в UpdateItemInfo)
     
    Каким образом?

    перегонять все в widestring видимо

    Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 10:18 21-08-2012
    Ichigo2



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Опять приветик.
    Вкратце суть такова -  моя программа загружает фотки в Timage, что не совсем быстро. А в каждом каталоге с фотками в системе есть файл Thumbs.db c эскизами. Можно ли из этого файлика загрузить в TImage миниатюры текущей директории и как?

    Всего записей: 153 | Зарегистр. 01-05-2011 | Отправлено: 10:18 21-08-2012
    A_V

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

    Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 10:39 21-08-2012
    Ichigo2



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    A_V
    О спасибо, а то дальше википедии я не ушел

    Всего записей: 153 | Зарегистр. 01-05-2011 | Отправлено: 10:43 21-08-2012
    Aleksandr N

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Подскажите по WinAPI
    Есть часть функции:
     
       DeskDC := GetDC(h_Wnd);
       hBmp := CreateCompatibleBitmap(DeskDC, ScrX, ScrY);
       DC := CreateCompatibleDC(DeskDC);
       SelectObject(DC, hbmp);
       BitBlt(DC, 0, 0, SCRX, SCRY, DeskDC, 0, 0, SrcCopy);
     
    Этот код создаёт картинку чужого контрола вместе с контролами, лежащими на нём. Например, если создавать картинку трея, то создаётся картинка вместе с иконками и часами.
    Как создать картинку БЕЗ поверх лежащих контролов?

    Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 19:29 21-08-2012
    A_V

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Aleksandr N
    Для конкретно указанного окна  - PrintWindow.
    Или ты хочешь, что-бы _дочерние_ контролы не отрисовались?

    Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 22:49 21-08-2012
    Aleksandr N

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    A_V
    Да, именно чтобы дочерние не отрисовались. PrintWindow пробывал, рисует всё как видишь.
     
    ИЛИ
    Поставим задачу иначе. Есть ещё часть функции
     
       hControlDC := BeginPaint(h_Wnd, PS);
       if hControlDC <> 0 then
        begin
         try
          iSavedID := SaveDC(hControlDC);
          SetWindowOrgEx(hControlDC, DeltaPosX, GetWindowSize(hNotifyWnd) - GetWindowSize(h_Wnd), nil);
          CallWindowProc(OldNotifyWndProc, hNotifyWnd, WM_PRINTCLIENT, hControlDC, PRF_CLIENT or PRF_ERASEBKGND);
          RestoreDC(hControlDC, iSavedID);
         finally
          EndPaint(h_Wnd, PS);
         end;
     
    она нормально рисует фон на нужном мне контроле. Но я не представляю как сюда вставить часть кода "забирающего" то что нарисовалось на нужном контроле (фон). Для примера опять тот-же трей, когда на окне часов рисуется фон за часами (текущее время, естественно, не видно что и требуется). Вот в это время нужно забрать то, что нарисовалось на часах.

    Всего записей: 1665 | Зарегистр. 25-02-2008 | Отправлено: 23:06 21-08-2012 | Исправлено: Aleksandr N, 23:21 21-08-2012
    vladok_7

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Всем привет, я начинаю изучать делфи по книге "Валерия Рубанцева" а  
    мне кое-что не понятно!
     
    там написано
     
    const
         num= 123;
         pi= 3.1415926
         Flag= TRUE  
                               //мне не понятно для чего нужны флаги! и для чего он нужен                        
     
     
    var s: single; //и что такое сингл тоже не понятно
     
    begin
        s:= num;
        s:= pi;
        s:=flag;
     
    .  .  .
     
    И НАПИСАНО : В данном примере действительной переменной s можно присвоить значение целого типа или действительного типа ,но никак не логического или строкового!!!                                                                                      
    ЧТО ОБЪЯСНИЛИ НЕ ПОНЯТНО!!!!

    Всего записей: 5 | Зарегистр. 02-02-2011 | Отправлено: 15:03 22-08-2012
    XPerformer



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    vladok_7
    В книжке должно быть написано что такое single - это тип, позволяющий хранить дробные значения. Такие переменные могут хранить и целые значения как частный случай дробных, но не других типов

    Всего записей: 2536 | Зарегистр. 20-06-2011 | Отправлено: 15:06 22-08-2012
    vladok_7

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Всем привет, я начинаю изучать делфи по книге "Валерия Рубанцева" а  
    мне кое-что не понятно!
     
    там написано
     
    const
         num= 123;
         pi= 3.1415926
         Flag= TRUE  
                               //мне не понятно для чего нужны флаги! и для чего он нужен                        
     
     
    var s: single; //и что такое сингл тоже не понятно
     
    begin
        s:= num;
        s:= pi;
        s:=flag;
     
    .  .  .
     
    И НАПИСАНО : В данном примере действительной переменной s можно присвоить значение целого типа или действительного типа ,но никак не логического или строкового!!!                                                                                      
    ЧТО ОБЪЯСНИЛИ НЕ ПОНЯТНО!!!!
     
    Добавлено:
    а что такое char

    Всего записей: 5 | Зарегистр. 02-02-2011 | Отправлено: 15:10 22-08-2012
    XPerformer



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    vladok_7
    char - это один символ. может, стоит другую книжку взять...

    Всего записей: 2536 | Зарегистр. 20-06-2011 | Отправлено: 15:19 22-08-2012
    vladok_7

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    посоветуй какую книгу по дельфе купить

    Всего записей: 5 | Зарегистр. 02-02-2011 | Отправлено: 15:22 22-08-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