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

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

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

ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 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

   

ShIvADeSt



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

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

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

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:09 28-06-2009 | Исправлено: psa1974, 12:00 02-02-2010
    KurkSS

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    здрасте все!
     
    Помогите советом...
     
    Есть два обьекта Главный и рабочий....
    главный даёт указание рабочему обработать данные, но НУЖНО СЛЕДУЮЩЕЕ ИЗМЕНИТЬ
     
    Главный делает
        Рабочий.Данные:="данные для обработки";
        Рабочий.Выполняй;//рабочий в отдельном потоке запустит процес обработки данных и
                                    //будет выполнен возврат из процедуры.
         
        Завершать:=Ложь;
        ПОКА Завершать<>Истина ДЕЛАЙ
        НАЧАЛО
           Интервал_времени:=СколькоМожноПодождать();
           Если ИнтервалВремени=0 ИЛИ Завершено=Истина  
              ТОГДА Завершать:=Истина
              Иначе sleep(ИнтервалВремени);
        КОНЕЦ;
        Если Завершено<>Истина ТОГДА НАчало Рабачий.Хватит;.............КОнец
    ...................................
     
    Рабочий.Выполняй//запускает запуск в отдельном потоке обработку данных
     
    Поток при нормальном завершении своей работы делает через synchronyze Главный.Завершено=Истина
     
    Рабочий.Хватит// зовершает принудительно поток.
     
    Что мне надо.... чтобы при нормальном завершении потока он не только сообщал о завершении но и выводил из ожидания главный обьект....
     
    Тоесть можно конечно сделать чтоб главный усыпал скажем на малый промежуток времени
    и часто в холостую просыпался... но так как диапазоны времени могут варьироваться от долей секунды до часов даже... хотелось бы както оптимальней сделать....
     
    Заранее спасибо

    Всего записей: 73 | Зарегистр. 22-05-2008 | Отправлено: 15:09 01-03-2010 | Исправлено: KurkSS, 15:12 01-03-2010
    Wahnsinn



    Junior Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    у тебя sleep используется только по сути для принудительного завершения, выведи к примеру процедуру по завершению рабочего потока в отдельный поток с параметром времени, если дочерний завершится раньше то завершаешь тот второй поток из главного иначе тот спустя заданное время прибьет рабочий.

    Всего записей: 129 | Зарегистр. 20-01-2007 | Отправлено: 16:28 01-03-2010
    V1s1ter



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    KurkSS
    Для начала напомню о теге MORE, который из шапки  
    Теперь по существу, как вариант можно разбить процедуру на две: первая запускает процесс, вторая обрабатывает результат работы процесса. Вторая процедура запускается рабочим процессом, который потом уничтожается. И никаких Sleep-ов.
    Запуск второй процедуры из рабочего процесса можео сделать и не напрямую, а через посылку сообщения.
     

    Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 16:49 01-03-2010
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Всем привет, назрел вопрос такого рода. Допустим есть массив:

    Код:
    AnsiList: Array [1..100] of AnsiString;

    В оконной процедуре окна требуется обработать индекс команды. Он равен индексу элемента в массиве. Когда массив фиксирован, можно указать диапазон значений по типу:

    Код:
        WM_COMMAND:
          begin
            case LoWord(wParam) of
              Low(AnsiList)..High(AnsiList):
                begin
                end;
            end;
          end;
     

    Но что делать если массив динамический? Можно ли упростить задачу? Я пока ничего лучше не придумал, как ввести 2 константы минимального и максимального значения, потом просто декремент делаю из LoWord(wParam) и получаю индекс в массиве. Вот хочется также сразу указать Low и High динамического массива, только компилятор ругается Constant expression expected.

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 21:49 01-03-2010
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
    если не принципиально использовать оператор  case, напиши так:

    Код:
        WM_COMMAND:  
          begin  
            if LoWord(wParam) - 1 in [Low(AnsiList)..High(AnsiList)] then
            begin  
            end;  
          end;

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 22:11 01-03-2010 | Исправлено: psa1974, 22:13 01-03-2010
    Maks150988



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

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

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

    Цитата:
    Wahnsinn

    я правильно понял тебя?
     
    1)Главный.ВызовВОтдельном потоке поцедуры, которая усыпает
    на заданный период времени, а вконце рабочему обьекту даёт команду на
    аварийное завершение.
     
    2)даём команду рабочему обьекту на выполнение.....
     
    Так а главному обьекту то что в это время делать????
    если 2) вызов метода и ожидать его завершения.... то как собственно 1)  
    тогда должен завершить принудительно это всё дело???
    Зы- я не профи а тока-тока учусь.... могу тормозить на простом.... можно
    шаблон кода, я наверно так быстрее пойму.
     

    Цитата:
    V1s1ter

    этот вариант для меня вобще сложный.... и не совсем понял слово процедура....
    где что именно оно означает....
     
     
     можно шаблон кода для случаяПодробнее...

    Всего записей: 73 | Зарегистр. 22-05-2008 | Отправлено: 02:17 02-03-2010
    V1s1ter



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    KurkSS
    Если я Вас правильно понял, то допустим управление происходит по нажатию на кнопку, тогда  
    Подробнее...
    И никто никого не ждет.

    Всего записей: 948 | Зарегистр. 06-02-2007 | Отправлено: 03:49 02-03-2010
    SIgor33

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    подскажите как считать значение из защищенной ячейки excel.
    из обычной я делаю так:
    var
       ExcelApp ,
       Workbook:OleVariant;
       Data:Real;
    begin
    ExcelApp.DisplayAlerts:=False;
    ExcelApp.AskToUpdateLinks:=False;
    Workbook := ExcelApp.WorkBooks.open(FileName);
    Data:= Workbook.Sheets['Лист'].Cells[1,1];
    end;
    а если она защищена то вываливается ошибка

    Всего записей: 652 | Зарегистр. 03-03-2009 | Отправлено: 09:37 02-03-2010
    Wahnsinn



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

    Код:
     
    xls := CreateOLEObject('Excel.Application');
    xlw := xls.WorkBooks.Open(FileName := 'd:\test.xls', Password := 'test', ReadOnly := True);
     

    Всего записей: 129 | Зарегистр. 20-01-2007 | Отправлено: 12:33 03-03-2010
    SIgor33

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Wahnsinn
    Вы не много не так поняли файл я открываю нормально и без пароля. Именно надо считать данные из защищенной ячейки. конечно можно снять командой unprotect защиту с листа. Но пароль меняется периодически. записывать данные в файл не нужно.
    Но ваш метод то же работает Спасибо

    Всего записей: 652 | Зарегистр. 03-03-2009 | Отправлено: 14:11 03-03-2010 | Исправлено: SIgor33, 14:17 03-03-2010
    Wahnsinn



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

    Код:
     
    uses ComObj;
    ...
    var
    XLApp, Sheet: OLEVariant;
    path, data: string;
    begin
    path:='d:\test.xls';
    XLApp := CreateOleObject('Excel.Application');
    XLApp.Workbooks.Open(path);
    Sheet := XLApp.Workbooks[ExtractFileName(path)].WorkSheets[1];
    data := XLApp.Cells[3,3];
    ...
    Sheet := UnAssigned;
    XLApp := UnAssigned;
    end;
     

    Всего записей: 129 | Зарегистр. 20-01-2007 | Отправлено: 16:01 03-03-2010
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Всем привет. такой вопрос. Мне нужно использовать OLE в программе, но я сделал свои модули, нужен чистый Api, а не суповой набор стандартных модулей. Так вот где надо вызывать функции CoInitialize и CoUninitialize, в initialization и finalization модуля или вначале выполнения программы инициализировать? Пробовал вызывать CoInitialize перед выполнением кода по созданию OLE объекта, вываливается в исключение.
    Сейчас сделал вызов этих функций в initialization и finalization, все работает номрально, но все же как-то думается это не самый оптимальный способ.

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 11:57 04-03-2010
    AviDen



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

    Цитата:
    Maks150988
    если не принципиально использовать оператор  case, напиши так:

    Код:
        WM_COMMAND:  
          begin  
            if LoWord(wParam) - 1 in [Low(AnsiList)..High(AnsiList)] then
            begin  
            end;  
          end;

    Кхм, так будет работать только в том случае, если размер массива не более 256 элементов. Да и вообще, чем вам if не угодил?
     
    Добавлено:
    Maks150988, совершенно необязательно вызывать это в Initizlization / Finalization (а в случае, если пишется DLL - то и вообще ошибочно, ибо, как гласит MSDN "Because there is no way to control the order in which in-process servers are loaded or unloaded, do not call CoInitialize, CoInitializeEx, or CoUninitialize from the DllMain function").
     
    Вызовы CoInitialize / CoUninitialize вполне могут быть вложены один в другой (главное - соблюсти парность). Даже более того, если какой-л. оле-объект создается для одноразового использования в какой-л. функции процедуре, можно в её начале инициализировать оле, а в конце - финализировать.
    Почему у тебя возникает исключение, сказать сложно, скорее всего, всё-таки где-то ты делаешь ole-вызов без предв. вызова OleInitialize.

    Всего записей: 316 | Зарегистр. 05-06-2007 | Отправлено: 19:05 05-03-2010 | Исправлено: AviDen, 19:06 05-03-2010
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    AviDen
     
    Код в самой программе, никаких своих dll не использую.
     

    Код:
    procedure UpdateTaskbarVisibleWindow;
    var
      TaskBar: ITaskBarList;
      pfList : IUnknown;
      hr     : HRESULT;
    begin
     
      CoInitialize(nil);
     
      try
     
        hr := CoCreateInstance(CLSID_TaskbarList, nil, CLSCTX_INPROC_SERVER or
          CLSCTX_LOCAL_SERVER, IUnknown, pfList);
     
        if (hr = S_OK) then
        try
          TaskBar := pfList as ITaskbarList;
          if (TaskBar.HrInit = S_OK) then
     
            if Boolean(dwTaskWindow) then
              begin
                TaskBar.AddTab(hMain);
                TaskBar.ActivateTab(hMain);
              end
            else
              TaskBar.DeleteTab(hMain);
     
        except;
        end;
     
      CoUninitialize;
     
      except
      end;
     
    end;

     
    Сейчас вот выдает Runtime Error 216. Хотя может я навернул в коде вызов CoUninitialize не туда.

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 19:59 05-03-2010
    AviDen



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

    Код:
    CoInitialize(nil);
    Try
       ...
    Finally
      CoUninitialize;
    End;

     
    Во-вторых, подавление исключений пустым except..end недопустимо
    И в третьих, я б тебе может и помог, но в исходниках vcl моего delphi7 объявления класса ITaskBarList нигде нет... У тебя какая версия, собссно?

    Всего записей: 316 | Зарегистр. 05-06-2007 | Отправлено: 21:02 05-03-2010
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    AviDen
    Да я тоже на 7 версии, но я свой модуль делал.
     

    Код:
    const  
      CLSID_TaskbarList: TGUID = '{56FDF344-FD6D-11d0-958A-006097C9A090}';
     
    type  
      ITaskbarList = interface
        ['{56FDF342-FD6D-11d0-958A-006097C9A090}']
          function HrInit: HRESULT; stdcall;
          function AddTab(hwnd: Cardinal): HRESULT; stdcall;
          function DeleteTab(hwnd: Cardinal): HRESULT; stdcall;
          function ActivateTab(hwnd: Cardinal): HRESULT; stdcall;
          function SetActiveAlt(hwnd: Cardinal): HRESULT; stdcall;
      end;

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 22:00 05-03-2010
    Odysseos



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Maks150988
     
    Я правильно понимаю, что это - попытка заюзать ProgressBar в панели задач Windows 7? Посмотрите вот на это - Windows 7 Components. Может быть, тут уже все есть?.. Сам ими пользуюсь, несмотря на beta-статус - прекрасно работают.

    Всего записей: 186 | Зарегистр. 02-01-2006 | Отправлено: 00:27 06-03-2010 | Исправлено: Odysseos, 00:42 06-03-2010
    andrewtishkin



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

    Цитата:
    попытка заюзать ProgressBar в панели задач Windows 7?

    Если нужно реализовать Progress Bars, Icon Overlays или Thumbnail Toolbars (названия беру согласно MSDN) и используется Delphi 2010, то там можно воспользоваться объявленными в ShlObj интерфейсами. Примеры есть в исходниках к книжке Delphi 2010 Handbook  (папка 05\Win7Taskbar)
     
    А насчёт остальных плюшек - лучше "Windows 7 Components" и правда ничего нет (imho)

    Всего записей: 781 | Зарегистр. 28-08-2008 | Отправлено: 01:07 06-03-2010
    Maks150988



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Да нет же, мне нужно скрывать/отображать окно мой программы в таскбаре. Есть конечно другой способ через SetWindowLong, но я проверял на висте и семерке - не работает что-то, пришлось через этот интерфейс делать. Через него все впорядке, но опять же что за фигня с инициализацией этого OLE. Ошибок нет только если в initialization явно указать CoInitialize. Неужто свободно нельзя проинициализировать эту долбанную COM библиотеку?

    Всего записей: 836 | Зарегистр. 23-12-2006 | Отправлено: 11:09 06-03-2010
       

    Страницы: 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 (до версии 2009) - часть 5
    ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215


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

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

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru