Приветствую!
Имеется WPF-приложение с поддержкой Drag&Drop. Перетаскиваешь файл на окно приложения - оно получает путь в нему.
Но, при запуске от имени администратора Drag&Drop не работает. Microsoft сделала это для предотвращения засылки данных из непривилегированного процесса в привилегированный.
Известно и решение - принудительное включение обработки соответствующих сообщений при помощи функций ChangeWindowMessageFilter/ChangeWindowMessageFilterEx.
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ALLOW);
ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ALLOW);
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ALLOW);
DragAcceptFiles(hWnd, TRUE);
И надо сказать этот способ работает в приложении, написанном на WinAPI.
Но, в приложении WPF данный способ категорически не хочет работать. Обработчики сообщений WM_COPYDATA, WM_COPYGLOBALDATA и WM_DROPFILES категорически не хотят включаться.
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
source.AddHook(WndProc);
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ALLOW);
ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ALLOW);
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ALLOW);
DragAcceptFiles(source.Handle, true);
}
private IntPtr WndProc(IntPtr Hwnd, Int32 Msg, IntPtr wParam, IntPtr lParam, ref Boolean Handled)
{
switch (Msg)
{
case WM_COPYDATA:
MessageBox.Show("WM_COPYDATA");
break;
case WM_COPYGLOBALDATA:
MessageBox.Show("WM_COPYGLOBALDATA");
break;
case WM_DROPFILES:
MessageBox.Show("WM_DROPFILES");
break;
case 0x2://WM_DESTROY
MessageBox.Show("WM_DESTROY");
break;
case 0x18://WM_SHOWWINDOW
DragAcceptFiles(Hwnd, true);
MessageBox.Show("WM_SHOWWINDOW");
break;
}
return IntPtr.Zero;
}
Другие сообщения обрабатываются. Для примера взял WM_DESTROY и WM_SHOWWINDOW.
Кто-нибудь знает, как заставить работать Drag&Drop в WPF под администратором?