OpenFileDialog в макросе VisualStudio

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by slesh, 20 Jun 2012.

  1. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    В общем появилась такая проблема:
    1) Для Visual Studio есть макрос (на VBA написанный)
    2) При его запуске создается окно
    3) При нажатии на кнопке в окне должен отобразиться диалог выбора файлов, но тут начинаются глюки.

    При попытке вызова OpenFileDialog1.ShowDialog() происходит ошибка
    При этом вне отладчика код наглухо зависает, приходится Visual Studio перезапускать.
    Пробовал везде задавать атрибут STAThread.
    Пробовал System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA)

    Нефига ничего не помогает. Или ошибка или зависание

    Если System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA) ставить перед OpenFileDialog1.ShowDialog(), то появляется ошибка:

     
  2. Feonor

    Feonor Elder - Старейшина

    Joined:
    23 Jul 2008
    Messages:
    128
    Likes Received:
    52
    Reputations:
    19
    0 все действо происходит из основного потока!
    1 поставьте атрибут [STAThread] перед процедурой которая вызывает OpenFileDialog1.ShowDialog().
    2 Перед OpenFileDialog1.ShowDialog() поставьте точку останова.
    3 посмотрите значение Thread.CurrentThread.ApartmentState

    что там?
     
    #2 Feonor, 20 Jun 2012
    Last edited: 20 Jun 2012
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 Feonor,
    1) ShowDialog запускается обработчике клика по кнопке.
    2) [STAThread] - это c# синтаксис, в VB чуть по другому но как я уже выше описал - не пашет, хоть ты где вставляй.
    3) Под отладчиком всегда будет появляться вышеуказанное исключение.
    4) перед вызовом ShowDialog, Thread.CurrentThread.ApartmentState
    = MTA
    5) Изменить ApartmentState неудаётся ниоткуда. Об этом я уже выше описал.
     
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    В общем проблему решил, через жопу но всёже. А именно
    1) Весь код из точки входа в модуль поместил в другую функции
    2) в точке входа создаю поток
    3) для потока задал ApartmentState = STA
    4) запустил потока

    Конечно работа макроса сразу прекратилась, но работа кода продолжилась нормально
     
  5. Feonor

    Feonor Elder - Старейшина

    Joined:
    23 Jul 2008
    Messages:
    128
    Likes Received:
    52
    Reputations:
    19
    ну тогда все нормально. еще как вариант извращения бекграуд воркер есть)
    PHP:
    private delegate DialogResult ShowSaveFileDialogInvoker();
    private 
    void backgroundWorker_DoWork(object senderDoWorkEventArgs e)
    {
    SaveFileDialog saveFileDialog = new SaveFileDialog();
    ShowSaveFileDialogInvoker invoker = new ShowSaveFileDialogInvoker(saveFileDialog.ShowDialog);
     
    this.Invoke(invoker); // where this is a Form
    }
    хотя у тебя там макрос.. ну сам смотри..
     
    2 people like this.
  6. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    У меня была проблема подобного типа, и я тоже искал костыли - в итоге получилось как у слэша.
    Однако, потом попросил глянуть код старшего коллегу - оказалось, я неправильно использовал сам вызов ShowDialog не верно. Подробности не помню, было более года тому назад - посмотрел увидел и забыл, но если выложишь кусок кода, то хотя бы смогу сказать отличается ли.
    Хотя я писал на C# не VBA, но разница думаю не существенна.

    Точно уже не помню, но какой то червячок засел и говорит о двух разных либах одна под Windows.Forms,а другая под WPF. Хотя долен признать, что уже и не помню.
     
    #6 Spot, 20 Jun 2012
    Last edited: 20 Jun 2012