|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Win10 переход на нужный рабочий стол
Добрый день!
Подскажите пожалуйста как создавать и переключать рабочие столы используя Win10 API |
#2
|
|||
|
|||
а что, в гугле забанили.
На запрос он даже сам дает маленькую табличку с описанием: Цитата:
|
#3
|
|||
|
|||
lmikle, я облазил весь инет перед тем как задавать вопрос, вы мне скопипастили текст на английском, хотя такого текста полно и на русском как это делать ручками, я ж спрашиваю использую WINAPI значит программно, например пользователь поместил мою программу на второй рабочий стол, потом ушел на первый рабочий стол, программа как завершила свои действия программно выполнит переход на тот рабочий стол где она находится, чтоб пользователь сразу увидел, да много для чего это нужно, если пользуешься virtualbox`ом то там давно реализована такая функция перехода на тот рабочий стол где выполнятся виртуальная машина.
|
#4
|
|||
|
|||
Кажись не весь облазил еще) нашел на забугорном форуме http://stackoverflow.com/questions/4...ager-in-delphi
Просто нужно было гуглить IVirtualDesktop и IVirtualDesktopManager, а на русском гуглил гуглил и ниче нужного не на гуглил, над исправлять это дело) |
#5
|
|||
|
|||
Нельзя так делать. Мало ли чем пользователь в это время занят.
Вставляй сообщение в Message Center. |
#6
|
|||
|
|||
Да об этом можно много рассуждать, кого-то это может раздражать когда чужая программа поверх сама внезапно становится, кого-то наоборот радовать что сразу перед их глазами и они сразу видят что нужно в ней сделать, а не нужно вчитываться в эти сообщения, конечно по всякой фигне отвлекать пользователя таким образом не собираюсь, да и опция будет как уведомлять.
Теперь давайте по теме) на том форуме я нашел рабочий код Код:
unit VDMUnit; interface uses Windows; function IsOnCurrentDesktop(wnd: HWND): Boolean; function GetWindowDesktopId(Wnd: HWND): TGUID; procedure MoveWindowToDesktop(Wnd: HWND; const DesktopID: TGUID); implementation uses ActiveX, Comobj; const IID_VDM: TGUID = '{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}'; CLSID_VDM: TGUID ='{AA509086-5CA9-4C25-8F95-589D3C07B48A}'; type IVirtualDesktopManager = interface(IUnknown) ['{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}'] function IsWindowOnCurrentVirtualDesktop(Wnd: HWND; out IsTrue: BOOL): HResult; stdcall; function GetWindowDesktopId(Wnd: HWND; out DesktopID: TGUID): HResult; stdcall; function MoveWindowToDesktop(Wnd: HWND; const DesktopID: TGUID): HResult; stdcall; end; function GetVDM: IVirtualDesktopManager; begin Result := nil; OleCheck(CoCreateInstance(CLSID_VDM, nil, CLSCTX_INPROC_SERVER, IVirtualDesktopManager, Result)); end; function IsOnCurrentDesktop(wnd: HWND): Boolean; var value: BOOL; begin OleCheck(GetVDM.IsWindowOnCurrentVirtualDesktop(Wnd, value)); Result := value; end; function GetWindowDesktopId(Wnd: HWND): TGUID; being OleCheck(GetVDM.GetWindowDesktopId(Wnd, Result)); end; procedure MoveWindowToDesktop(Wnd: HWND; const DesktopID: TGUID); begin OleCheck(GetVDM.MoveWindowToDesktop(Wnd, DesktopID)); end; end. А как программно перейти к нужному рабочему? Вот я получил TGUID рабочего стола на котором находится моя программа, пользователь сидит на первом рабочем столе и что нужно выполнить чтобы произошел переход к рабочему столу где находится моя программа? Читал что нужный рабочий стол автоматически активируется если передать фокус программе, но уже перепробовал разные функции для передачи фокуса программе, единственно Код:
SetForegroundWindow(application.MainFormHandle); |
#7
|
||||
|
||||
Попробуй через другой интерфейс GitHub
(SwitchDesktop) Код:
MIDL_INTERFACE("f31574d6-b682-4cdc-bd56-1827860abec6") IVirtualDesktopManagerInternal : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE GetCount( UINT *pCount) = 0; virtual HRESULT STDMETHODCALLTYPE MoveViewToDesktop( IApplicationView *pView, IVirtualDesktop *pDesktop) = 0; // Since build 10240 virtual HRESULT STDMETHODCALLTYPE CanViewMoveDesktops( IApplicationView *pView, int *pfCanViewMoveDesktops) = 0; virtual HRESULT STDMETHODCALLTYPE GetCurrentDesktop( IVirtualDesktop** desktop) = 0; virtual HRESULT STDMETHODCALLTYPE GetDesktops( IObjectArray **ppDesktops) = 0; virtual HRESULT STDMETHODCALLTYPE GetAdjacentDesktop( IVirtualDesktop *pDesktopReference, AdjacentDesktop uDirection, IVirtualDesktop **ppAdjacentDesktop) = 0; virtual HRESULT STDMETHODCALLTYPE SwitchDesktop( IVirtualDesktop *pDesktop) = 0; virtual HRESULT STDMETHODCALLTYPE CreateDesktopW( IVirtualDesktop **ppNewDesktop) = 0; virtual HRESULT STDMETHODCALLTYPE RemoveDesktop( IVirtualDesktop *pRemove, IVirtualDesktop *pFallbackDesktop) = 0; // Since build 10240 virtual HRESULT STDMETHODCALLTYPE FindDesktop( GUID *desktopId, IVirtualDesktop **ppDesktop) = 0; }; // aa509086-5ca9-4c25-8f95-589d3c07b48a ? MIDL_INTERFACE("a5cd92ff-29be-454c-8d04-d82879fb3f1b") IVirtualDesktopManager : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE IsWindowOnCurrentVirtualDesktop( /* [in] */ __RPC__in HWND topLevelWindow, /* [out] */ __RPC__out BOOL *onCurrentDesktop) = 0; virtual HRESULT STDMETHODCALLTYPE GetWindowDesktopId( /* [in] */ __RPC__in HWND topLevelWindow, /* [out] */ __RPC__out GUID *desktopId) = 0; virtual HRESULT STDMETHODCALLTYPE MoveWindowToDesktop( /* [in] */ __RPC__in HWND topLevelWindow, /* [in] */ __RPC__in REFGUID desktopId) = 0; }; Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение: | ||
TidusX (16.02.2017)
|
#8
|
|||
|
|||
О благодарю, осталось вспомнить навыки программирования по си))) чтоб перевести его на делфи, а то меня хоть и учили в институте по нему кодить, но мне больше нравится синтаксис делфи, он более проще и понятней и о си уже как 5 лет не вспоминаю)
|
#9
|
|||
|
|||
Спасибо всем отписавшимся, провозился пол дня так и не получилось перевести на делфийский, там оказалось не всё так просто, поэтому для себя нашел другое решение, а именно готовая библиотека VirtualDesktopAccessor.dll в которой реализизованы эти функции, подключил к своему приложению и вызываю нужные процедуры. Кому нужно пользуйтесь
https://github.com/Ciantic/VirtualDesktopAccessor |
#10
|
|||
|
|||
Дык это IDL.
Перевод по аналогии с тем, который ты уже нашел. Ну или можно попробовать импортировать чеерз Import ActiveX меню, если сможешь найти этот интерфейс в списке. Только при импорте просто создавай файл, не надо генерировать компонент для палитры. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
TidusX (16.02.2017)
|
#11
|
|||
|
|||
Попробую, спасибо.
|
#12
|
||||
|
||||
В принципе не особо сложного было перевести. Однако пои познания в С настолько скудны, что я не смог перевести в Delphi
Код:
virtual HRESULT STDMETHODCALLTYPE GetDesktops( IObjectArray **ppDesktops) = 0; Так что если спецы подскажут, буду премного благодарен. А так, вот функция выводит количество виртуальных десктопов. Остается только перевести остальные ф-ции и задача решена. Код:
unit uVDMI; interface uses Windows, ActiveX, Comobj; const CLSID_ImmersiveShell: TGUID = '{C2F03A33-21F5-47FA-B4BB-156362A2F239}'; CLSID_VDMI: TGUID = '{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}'; // 10130 // 10240 // 14393 IID_IVDMI_ARRAY: array [0..2] of TGUID = ('{EF9F1A6C-D3CC-4358-B712-F84B635BEBE7}', '{AF8DA486-95BB-4460-B3B7-6E7A6B2962B5}', '{F31574D6-B682-4CDC-BD56-1827860ABEC6}'); type IVirtualDesktopManagerInternal = interface(IUnknown) // ['{F31574D6-B682-4CDC-BD56-1827860ABEC6}'] function GetCount(Count: PUINT): HRESULT; stdcall; function notimpl1(): HRESULT; stdcall; function notimpl2(): HRESULT; stdcall; function notimpl3(): HRESULT; stdcall; function notimpl4(): HRESULT; stdcall; function notimpl5(): HRESULT; stdcall; function notimpl6(): HRESULT; stdcall; function notimpl7(): HRESULT; stdcall; function notimpl8(): HRESULT; stdcall; function notimpl9(): HRESULT; stdcall; end; function GetDesktopCount: Cardinal; implementation function GetDesktopCount: Cardinal; var shell: IServiceProvider; VDMI: IVirtualDesktopManagerInternal; i: Integer; begin Result := 0; if Succeeded(CoCreateInstance(CLSID_ImmersiveShell, nil, CLSCTX_LOCAL_SERVER, IServiceProvider, shell)) then begin for i := Low(IID_IVDMI_ARRAY) to High(IID_IVDMI_ARRAY) do if Succeeded(shell.QueryService(CLSID_VDMI, IID_IVDMI_ARRAY[i], VDMI)) then begin VDMI.GetCount(@Result); VDMI._Release; Break; end; shell._Release; end; end; end. Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. Последний раз редактировалось dr. F.I.N., 16.02.2017 в 19:35. |
Этот пользователь сказал Спасибо dr. F.I.N. за это полезное сообщение: | ||
TidusX (16.02.2017)
|
#13
|
|||
|
|||
Браво! Проверил всё правильно показывает кол-во столов, ну да остальные функции до ума довести осталось и на этом форуме появится раньше дельфийский такой модуль) а если попробовать обойтись пока без **ppDesktop? Чтобы функцию замутить SwitchDesktop нужно написать интерфейс IVirtualDesktop, и создать структуру IApplicationView, там указатель на указатель не нужно делать.
|
#14
|
||||
|
||||
Столкнулся с еще одно проблемой. В зависимости от сборки винды IID_IVDMI может иметь три разных значения. Переделал для стабильной работы, функцию укоротил (попробую отредактировать предыдущее сообщение).
Что касается остального, то с интерфейсом IApplicationView не все так однозначно. По нему описания практически нету. Да и проще найти GUID экрана на котором программа и сравнить с активным, после чего переключить при необходимости. Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |
#15
|
||||
|
||||
Вопрос решен. Постараюсь завтра выложить готовый модуль. Может кому и пригодится.
Грамотно поставленный вопрос содержит не менее 50% ответа. Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть. |