Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.02.2017, 20:02
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию Win10 переход на нужный рабочий стол

Добрый день!

Подскажите пожалуйста как создавать и переключать рабочие столы используя Win10 API
Ответить с цитированием
  #2  
Старый 15.02.2017, 20:25
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,052
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

а что, в гугле забанили.
На запрос он даже сам дает маленькую табличку с описанием:
Цитата:
Сообщение от google
How to create a new virtual desktop in Windows 10
Click the Task View button in your taskbar. It looks like a square over a rectangle. You can also simultaneously hit the Windows key and Tab key together on your keyboard.
Click New Desktop. It's located in the bottom right corner of your screen.
Ответить с цитированием
  #3  
Старый 15.02.2017, 20:32
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

lmikle, я облазил весь инет перед тем как задавать вопрос, вы мне скопипастили текст на английском, хотя такого текста полно и на русском как это делать ручками, я ж спрашиваю использую WINAPI значит программно, например пользователь поместил мою программу на второй рабочий стол, потом ушел на первый рабочий стол, программа как завершила свои действия программно выполнит переход на тот рабочий стол где она находится, чтоб пользователь сразу увидел, да много для чего это нужно, если пользуешься virtualbox`ом то там давно реализована такая функция перехода на тот рабочий стол где выполнятся виртуальная машина.
Ответить с цитированием
  #4  
Старый 15.02.2017, 21:29
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

Кажись не весь облазил еще) нашел на забугорном форуме http://stackoverflow.com/questions/4...ager-in-delphi
Просто нужно было гуглить IVirtualDesktop и IVirtualDesktopManager, а на русском гуглил гуглил и ниче нужного не на гуглил, над исправлять это дело)
Ответить с цитированием
  #5  
Старый 16.02.2017, 02:44
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,052
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Нельзя так делать. Мало ли чем пользователь в это время занят.
Вставляй сообщение в Message Center.
Ответить с цитированием
  #6  
Старый 16.02.2017, 10:52
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

Да об этом можно много рассуждать, кого-то это может раздражать когда чужая программа поверх сама внезапно становится, кого-то наоборот радовать что сразу перед их глазами и они сразу видят что нужно в ней сделать, а не нужно вчитываться в эти сообщения, конечно по всякой фигне отвлекать пользователя таким образом не собираюсь, да и опция будет как уведомлять.
Теперь давайте по теме) на том форуме я нашел рабочий код
Код:
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.
Там всего три функции IsOnCurrentDesktop(wnd: HWND): Boolean; эта чтобы проверить хэндл окна находится ли он на текущем рабочем столе, GetWindowDesktopId(Wnd: HWND): TGUID; эта возращает TGUID рабочего стола хендл окна которого хотим проверить, и этой MoveWindowToDesktop(Wnd: HWND; const DesktopID: TGUID) можно отправить наше окно на нужный рабочий стол.
А как программно перейти к нужному рабочему? Вот я получил TGUID рабочего стола на котором находится моя программа, пользователь сидит на первом рабочем столе и что нужно выполнить чтобы произошел переход к рабочему столу где находится моя программа? Читал что нужный рабочий стол автоматически активируется если передать фокус программе, но уже перепробовал разные функции для передачи фокуса программе, единственно
Код:
SetForegroundWindow(application.MainFormHandle);
дает признаки, иконка программы начинает мигать на панели задач, когда по ней кликнешь то сразу выполняется переход на тот рабочий стол, но хотелось бы это все программно, VirtualBox умеет переходить к нужному рабочему столу где работает его виртуальная машина как он так замутил, или хитрым способом программно клацает горячую клавишу CTRL+WIN+стрелка влево/вправо для перехода на нужный рабочий стол, но для этого нужно знать тогда текущую позицию рабочего стола и отсчитывать кол-во нажатий до позицию нужного рабочего стола.
Ответить с цитированием
  #7  
Старый 16.02.2017, 11:35
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Попробуй через другой интерфейс 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  
Старый 16.02.2017, 11:42
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

О благодарю, осталось вспомнить навыки программирования по си))) чтоб перевести его на делфи, а то меня хоть и учили в институте по нему кодить, но мне больше нравится синтаксис делфи, он более проще и понятней и о си уже как 5 лет не вспоминаю)
Ответить с цитированием
  #9  
Старый 16.02.2017, 18:21
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

Спасибо всем отписавшимся, провозился пол дня так и не получилось перевести на делфийский, там оказалось не всё так просто, поэтому для себя нашел другое решение, а именно готовая библиотека VirtualDesktopAccessor.dll в которой реализизованы эти функции, подключил к своему приложению и вызываю нужные процедуры. Кому нужно пользуйтесь
https://github.com/Ciantic/VirtualDesktopAccessor
Ответить с цитированием
  #10  
Старый 16.02.2017, 18:21
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,052
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Дык это IDL.
Перевод по аналогии с тем, который ты уже нашел.
Ну или можно попробовать импортировать чеерз Import ActiveX меню, если сможешь найти этот интерфейс в списке. Только при импорте просто создавай файл, не надо генерировать компонент для палитры.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
TidusX (16.02.2017)
  #11  
Старый 16.02.2017, 18:23
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

Попробую, спасибо.
Ответить с цитированием
  #12  
Старый 16.02.2017, 19:10
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

В принципе не особо сложного было перевести. Однако пои познания в С настолько скудны, что я не смог перевести в Delphi
Код:
virtual HRESULT STDMETHODCALLTYPE GetDesktops(
IObjectArray **ppDesktops) = 0;
Не могу допетрить как извратиться с **ppDesktop (указатель на указатель).
Так что если спецы подскажут, буду премного благодарен.

А так, вот функция выводит количество виртуальных десктопов. Остается только перевести остальные ф-ции и задача решена.
Код:
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  
Старый 16.02.2017, 19:27
TidusX TidusX вне форума
Прохожий
 
Регистрация: 20.10.2013
Сообщения: 19
Версия Delphi: XE10.2 Tokyo
Репутация: 10
По умолчанию

Браво! Проверил всё правильно показывает кол-во столов, ну да остальные функции до ума довести осталось и на этом форуме появится раньше дельфийский такой модуль) а если попробовать обойтись пока без **ppDesktop? Чтобы функцию замутить SwitchDesktop нужно написать интерфейс IVirtualDesktop, и создать структуру IApplicationView, там указатель на указатель не нужно делать.
Ответить с цитированием
  #14  
Старый 16.02.2017, 19:31
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Столкнулся с еще одно проблемой. В зависимости от сборки винды IID_IVDMI может иметь три разных значения. Переделал для стабильной работы, функцию укоротил (попробую отредактировать предыдущее сообщение).

Что касается остального, то с интерфейсом IApplicationView не все так однозначно. По нему описания практически нету. Да и проще найти GUID экрана на котором программа и сравнить с активным, после чего переключить при необходимости.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
  #15  
Старый 16.02.2017, 20:26
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 660
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Вопрос решен. Постараюсь завтра выложить готовый модуль. Может кому и пригодится.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 01:56.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter