[Delphi] Как вывести диалог из компонента?

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by RedFern.89, 12 May 2010.

  1. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    Всем доброго времени суток! Вопрос такой. Как вывести диалог из компонента, причем вывести так, что выполнение дальнейшего кода продолжится, пока не закроешь диалог? Диалог примерно такой:

    [​IMG]
     
  2. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    ShowModal или что-то в таком духе. Дельфи почти забыл. Для форм был такой метод.
     
  3. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    как то не очень то хотелось бы пихать модуль Forms в компоент. Диалог должен состоять из панели.
     
  4. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    WinAPI?
    Панель то ты куда-то должен поместить
     
  5. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    а будет ли грамотно, если в компоненте будет такой код:

    Code:
    uses frmDialogs;
    
    ...
    
    function TidVKClient.Login(): boolean;
    begin
      { код логина }
     // если капча, показать диалог
     Dlg.ShowModal; 
     { продолжение выполнения кода }
    end;
    
    
     
  6. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Не хочешь подключать формс к своему классу - просто создай событие у своего компонента типа TidVKClient.OnCatcha. В обработчик этого события передавай stream с пикчей, а тот кто будет использовать твой компонент извне - будет обрабатывать событие, например либо капчу показать в модальном окне, либо отправить на антигейт и т.п.
     
  7. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    так ведь надо же еще выполнение код приостановить как то о_О
     
  8. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    ShowModal в данном случае будет нормально.
     
  9. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    так и сделал)) помог следующий код:

    Code:
    // ---- Вывод диалога ввода кода капчи ----
    procedure TidVKClient.ShowCaptchaDialog(const captcha_sid: string);
    var
      MS  : TMemoryStream;
      Jpg : TJpegImage;
    begin
       Ms  := TMemoryStream.Create;
       Jpg := TJpegImage.Create;
       Get('http://vkontakte.ru/captcha.php?s=1&sid=' + captcha_sid, Ms);
       Ms.Position := 0;
       Jpg.LoadFromStream(ms);
       DlgForm.imgKey.Picture.Graphic := Jpg;
       Jpg.Free;
       Ms.Free;
       DlgForm.Caption := 'Enter Code';
       DlgForm.ShowModal;
    end;
    
    однако меня этот uses Forms; не улыбает вовсе
     
  10. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Раз не нравится сделай панель в памяти по данным dfm файла твоего диалога(всё ручками), потом с winapi создавай обычное окно без заголовка и через Windows.SetParent на то окно лепи панельку.

    P.S. Если уж делаешь компонент, то делай универсальнее и более гибкий код. Кстати вышеуказаный код должен быть в таким;)
    Code:
    // ---- Вывод диалога ввода кода капчи ----
    procedure TidVKClient.ShowCaptchaDialog(const captcha_sid: string; const notice : String = 'Enter Code');
    var
      MS  : TMemoryStream;
      Jpg : TJpegImage;
    begin
       Ms  := TMemoryStream.Create;
       Jpg := TJpegImage.Create;
       try
         Get('http://vkontakte.ru/captcha.php?s=1&sid=' + captcha_sid, Ms);
         Ms.Position := 0;
         Jpg.LoadFromStream(ms); {при не правльных данных здесь может вылезть эксцепшн}
         //DlgForm.imgKey.Picture.Graphic := Jpg; {не верно, нужно делать через Assign, ибо будет утечка памяти и при хз что будет когда Jpg сделают Free}
         DlgForm.imgKey.Picture.Assign(Jpg); {Делфи под боком нет, так что не помню, на Graphic или сразу на Picture Assign делать)}
       finally  
         Jpg.Free;
         Ms.Free;
       end;
       DlgForm.Caption := notice;
       DlgForm.ShowModal;
    end;
     
    3 people like this.
  11. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Jingo Bo, немножечко ошибаешься. RedFern.89 не использует Indy, для работы с инетом, а работает с помощью своих функций.

    Так что ему виднее, будет ли exception, или нет.
     
  12. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Chrome~ при чем здесь инди :confused: ?
    И сигнатура кстати похожая на Indy все же у Get
     
  13. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Ты ничего не понял просто.

    Блок
    Code:
       try
       finally  
       end;
    не есть обязательным, так как не факт, что в нем произойдет exception. Может быть функция Get всегда возвращает правильный результат автору? ))
     
  14. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Имхо наоборот, ты ничего не понял
    Вот что пишет Джинго Бо:
    Если в Ms не содержится пикча то будет экспешн, да. Генерирует этот экспешн JpgImage или как там класс называется не помню
    Всегда возвращает правильный результат, тем более при работе с сетью - такого не бывает. И причин этого может быть сколько угодно. Что она вернет если вырубиться инет на машине? Правильный результат? А если дохлый прокси будет?
     
  15. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    Сорри, сглупил. Не дочитал код и не обратил внимание.
     
  16. RedFern.89

    RedFern.89 Member

    Joined:
    20 Jan 2010
    Messages:
    557
    Likes Received:
    45
    Reputations:
    0
    Метод GET я сделал на winapi))) эксепшенов быть не должно))) всем спасибо за помощь))

    Jingo Bo, как сделать такую панель? можно какнить кодом показать?))) буду очень благодарен))
     
  17. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    Я try-finally поставил из-за того что при загрузке jpg может вылезть exception, а растянул до get потому что не знал может она создать exception или нет.
    По поводу кода могу сказать вот что. Создаёшь в какой нить програмке для ресурсов диалог, сохраняешь в rc-файл. Потом берешь прогу из набора delphi - BRCC32.EXE(находится там же где и exe delphi). В командной строке прописываешь :
    <путь к BRCC32> <путь к твоему RC файлу> Прога тебе выдаст файл ресурсов для delphi. Кидаешь в свой проект, подключаешь в исходниках {$R твой тот файл.res} И делаешь как в статье http://www.delphisources.ru/pages/faq/base/write_win32api_apps.html

    Кода получится не много и без forms:) Хотя смысла его не использовать я не вижу, т.к. юзаться код полюбому будет с vcl-формами.