Форум: "WinAPI";
Текущий архив: 2003.12.04;
Скачать: [xml.tar.bz2];
ВнизCoInitialize и OpenDialog Найти похожие ветки
← →
misterix (2003-10-02 17:54) [0]Если установить флаг CoInitFlags := COINIT_MULTITHREADED
а потом вызвать OpenDialog, то при нажатии, на боковой панели, кнопки Мои Документы, приложение виснет. Трассировка показала, что в этом случае в некоторых функциях начинающихся с префикса Nt происходят Access Violation. Кто-нибудь знает, как это обойти. Без флага COINIT_MULTITHREADED не могу обойтись.
← →
me (2003-10-02 19:11) [1]MSDN: INFO: Calling Shell Functions and Interfaces from a Multithreaded Apartment
SUMMARY
When you call or access a shell function or shell interface from a thread that has been initialized as a multithreaded apartment, the function or interface may have its functionality impaired or completely fail.
MORE INFORMATION
A call to CoInitializeEx(COINIT_MULTITHREADED) allows calls to objects created on the calling thread to be run on any thread. When accessing objects that use the apartment threading model from a multithreaded apartment, COM will synchronize access to the object. In order for this synchronization to occur, COM must marshal calls to the object. Because the shell currently does not provide the necessary information, either through a type library or proxy/stub code, for its objects to be marshaled, attempts to access shell objects from a multithreaded apartment fail.
The following are examples of how calls to CoInitializeEx(COINIT_MULTITHREADED) can affect functions that rely on shell objects:
GetOpenFileName/GetSaveFileName
Users can navigate to namespace extension folders such as "My Documents" through the Open and Save As dialog boxes. However, these folders cannot be browsed to because the browser cannot create the required interfaces, such as IShellFolder
← →
misterix (2003-10-03 17:08) [2]Спасибо. Придется забить на этот сайдбар.
← →
misterix (2003-10-06 18:07) [3]Выход из этой ситуации все же нашелся. Конечно, самый простой выход это отказаться от сайдбара. Но не всегда это проходит. Так, данный вариант не прошел и в моем случае. Чтобы отказаться от сайдбара нужно не высталять флаг OFN_EXPLORER в свойствах диалогового окна (в object inspector это флаг ofExNoPlacesBar в группе OptionsEx). Но в некоторых случаях этот флаг необходим. Например Regedit использует свои интерфесые элементы, которые добавляются на стандартное диалоговое окно при эксопрте ветки реестра. У меня делалось то же самое, а без указания флага OFN_EXPLORER ничего не получится, поэтому отказаться от данного флага я не мог.
Хорошо, что на моей работе попался коллега, который очень любит забавляться с потоками. Оказалось, что если запустить вывод диалогового окна открытия файла в отдельном потоке, то все будет работать нормально(кстати, под ХР и так все работает).
Ну и, собственно, кому интересно, привожу модуль с реализацией данного метода.
unit OpenDlgMultyThread;
interface
uses
Dialogs;
function SafeRunOpenDialog(dlg: TOpenDialog): Boolean;
implementation
uses
Classes, ActiveX;
type
TRunThread = class(TThread)
private
FDlg: TOpenDialog;
FRes: Boolean;
protected
procedure Execute; override;
public
property Dlg: TOpenDialog read FDlg write FDlg;
property Res: Boolean read FRes;
end;
{ TRunThread }
procedure TRunThread.Execute;
begin
CoInitialize(nil);
try
FRes := Dlg.Execute;
finally
CoUnInitialize;
end;
end;
function SafeRunOpenDialog(dlg: TOpenDialog): Boolean;
var
P: TRunThread;
begin
p := TRunThread.Create(true);
try
p.Dlg := dlg;
p.Resume;
p.WaitFor;
result := p.Res;
finally
p.Free;
end;
end;
end.
Вот так. Вызываем функцию SafeRunOpenDialog передав ей в качестве параметра TOpenDialog или TSaveDialog и радуемся жизни.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2003.12.04;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.005 c