Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Управлеине фокусом ввода


Автор: Zero 13.11.2004, 19:09
Привет народ!!!
У меня такой вопрос, как сделать чтобы форма не могла получить фокус ввода (например как кнопка TSpeedButton), т.е. чтобы вам было более понятно, то могу сказать так: я делаю курсач на тему, создание рабочего стола, в нём создано некоторое количество форм, но главная форма на которой находятся ярлыки, если она получает фокус ввода, а при этом открыты др. окна, то они (как бы) закрываются.
...А ещё лучше бы сделать так чтобы, форма могла получать фокус ввода, но всегда была позади остальных окон, как сам стандартный Desktop.
Заранее благодарен!!!

Автор: Girder 15.11.2004, 21:00
В архиве два варианта решения:
1)Через обработку сообщения
2)Через Explorer

Второй вариант банальный smile и неинтересный... хотя и без глючный smile

Удачи.

Автор: Zero 15.11.2004, 23:19
Girder, спаибо конечно, на твоём примере, работает замичательно, но я здесь непонял как ты всё делал, за счёт исп. большого кол-ва API, но попробывал, просто воткнуть всё что есть в своё главное окно, которое иметирует рабочий стол, и тут всё глюкнуло, да впредачу открылись остальные дополнительно созданые формы.
Не знаеш способа попроще, или догадатся почему у меня мог быть глюк??? smile

Автор: Girder 16.11.2004, 09:45
Цитата(Zero @ 15.11.2004, 23:19)
Не знаеш способа попроще, или догадатся почему у меня мог быть глюк??? 
Попробывал у себя... дополнительно создавал окна... диалоги... все работает smile . Кинь мне на мыло... свой пример.

PS: Я не телепат... smile но думаю что ты не правильно перенес код... smile

Автор: Zero 16.11.2004, 18:35
Гирдер, проверь свою почту, там тебе посылка...
Только когда распакуешь, перед запуском, в файле Regedit.txt, незабудь указать путь к папке Desktop, пример там есть (т.е. путь на моём компе...)
Цитата
Я не телепат...

Ладно, насчёт догодатся...Это я так сказал, к слову, просто я думал что ты напишеш, что-нибудь попроще...
И кстати, на счёт дополнительно-создаваемых, форм: я их тоже создавл в твоём файле, там глюков небыло...

Заранее спасибо!!! smile

Автор: Girder 16.11.2004, 21:58
Цитата(Zero @ 16.11.2004, 18:35)
Гирдер, проверь свою почту, там тебе посылка...
Все получил... уже исправил и отправил. Много лишнего кода закоментировал, т.ч. ты поудаляй там его... а то мне лень... smile

И еще: я там отвезался от жесткой привязки к пути, но вроде не везде... smile проверь

Удачи.

Автор: Zero 16.11.2004, 22:46
Girder, спасибо за попытку исправить, но всётаки те глюки про которые я тебе говорил (например окно, переключения между языками и.т.п.) там загружается при запуске программы.
Цитата
я там отвезался от жесткой привязки к пути, но вроде не везде...

Я специально сделал файл Regedit.txt, чтобы там определялся путь к exe-файлу. т.к. программно я недадумался как это реализовать.
Я не знаю чё ещё ты там нахимичил, но теперь там ещё и открытие многих вещей (например окно соответствуюющее кнопки пуск) открывается ниже чем надо...
Но ладно, все эти мелочи, всё ерунда, самое главное, почему у тебя всё работате без глюков, а у меня опять всё не так как надо. smile smile smile
Girder, а незнаеш, может есть какая-нибудь WinAPI, чтобы сделать окно постоянно позади всех др. окон, для примера, вот так можно сделать чтобы окно всегда было поверх остальных окон и обратно
Код

SetWindowPos(Form1.Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);  //Поверх всех окон
SetWindowPos(Form1.Handle,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);  //Обратно

Заранее благодарен!!!

Автор: Girder 16.11.2004, 23:47
Цитата(Zero @ 16.11.2004, 22:46)
говорил (например окно, переключения между языками и.т.п.) там загружается при запуске программы.
Ента ошибка уже не моя, а твоя. Или надо не создавать окно при запуске, а потом когда надо создавать/удалять. Или работать через Visible.
Цитата(Zero @ 16.11.2004, 22:46)
Я специально сделал файл Regedit.txt, чтобы там определялся путь к exe-файлу. т.к. программно я недадумался как это реализовать.
Уже реализовал... ( smile ParamStr(0) smile ) в том примере... что тебе послал.
Цитата(Zero @ 16.11.2004, 22:46)
Я не знаю чё ещё ты там нахимичил
Много... smile
Цитата(Zero @ 16.11.2004, 22:46)
Я не знаю чё ещё ты там нахимичил, но теперь там ещё и открытие многих вещей (например окно соответствуюющее кнопки пуск) открывается ниже чем надо...
Енто опять же тебе надо свой код подправить, а не тот что я тебе внедрил... smile

Цитата(Zero @ 16.11.2004, 22:46)
Girder, а незнаеш, может есть какая-нибудь WinAPI
Нету... smile Самы простой способ, теперь в твоей программе.

Ладно... еще щас посмотрю и вышлю...

Удачи.

Автор: Zero 17.11.2004, 04:46
Добрый ночи Girder, спасибо что выслал мне второй вариант!!! smile
Я уже 5 часов сижу его разбераю, и переделываю, но всётаки мне не совсем понятны некоторые вещи... smile
Не мог бы ты мне немного пояснить, след...
Во первых как ты умудрился убрать строку
Код

WindowState:=wsMaximized

И при этом как-то экран всё равно увеличивается... smile
А, да кстати, спасибо тебе что помог мне избавится от привязки к Regedit.txt, ото я сам это пытался сделать, но так и не получилось, а создавать тему с такими тупыми вопросами и отвликать всех мне не хотелось, поэтому и пришлось делать всякие примудрости. smile
Ладно, что-то я отвлёкся, ещё уменя, такие вопросы по коду:
Код

Var
 PR_HWND:HWND=0;          //Что такое,
 Tray_HWND:HWND=0;       //означает тип HWND
 Tray_Parent:HWND=0;      //и зачем, ты их по умолчанию
 PR_HWND_Def:HWND=0;  //везде приравниваеш
 MSTask:HWND=0;             //к нулю
 MSTask_Parent:HWND=0;

Потом процедура WndProc, это вообще просто тёмный лес
Код

procedure TMain_Desktop.WndProc(var Message: TMessage);
begin
if (Message.Msg=WM_SYSCOMMAND)and(Message.WParam=SC_MINIMIZE) then
  Message.Result:=0 else inherited WndProc(Message);
end;

Потом, я часто встречаю, употребление слов Хендл, но доконца немогу понять их смысла smile
Ну, т.е. в процедуре создания формы, есть два цикла, что каждый из них делает... smile
1─ый цикл
Код

h1:=Handle;
 repeat
   h:=GetWindow(h1,GW_OWNER);
   if h<>0 then h1:=h;
 until (h=0);
 h:=GetWindow(h1,GW_HWNDFIRST);

2─цикл
Код

h1:=0;
 while (h<>0) do
   begin
     h1:=h;
     h:=GetWindow(h1,gw_hWndNext);
   end;
 PR_HWND:=h1;

Потом в процедуре OnActive, я пологаю ты сделал чтобы прогу, можно было сворачивать??? Но каким образом это происходит??? Я понял только некоторую часть процедуры, но из-за того что многое непонял, не могу понять смысла её работы:
Код

...
begin
  Tray_HWND:=findwindow('Shell_Traywnd',nil);  //???
  h:=findwindowex(Tray_HWND,0,'ReBarWindow32', nil); //???
  MSTask:=findwindowex(h,0,'MSTaskSwWClass', nil);  //???
  Tray_Parent:=Windows.SetParent(Tray_HWND,pTray.Handle);  //???
  MSTask_Parent:=Windows.SetParent(MSTask,PBZ.Panel5.Handle);  //???
  pTray.Visible:=false;  //зачем делать панель которая должна исчезнуть???
  Start:=true;
  Top:=0;
  Left:=0;
  Width:=Screen.Width;
  Height:=Screen.Height;
  Main_Desktop.SetFocus;
  Main_Desktop.Repaint;  //???
  PR_HWND_Def:=findwindowex(PR_HWND,0,'SHELLDLL_DefView',nil);  //???
  if PR_HWND<>0 then Windows.SetParent(Handle,PR_HWND);  //???
  showwindow(PR_HWND_Def,SW_Hide);  //???
 end;
...

Там где стоят вопросы, я непонял... smile
Ещё, зачем нужна вот эта процедура, что она делает???
Код

procedure TMain_Desktop.FormDestroy(Sender: TObject);
begin
 Windows.SetParent(Tray_HWND,Tray_Parent);
 showwindow(PR_HWND_Def,SW_Show);
end;

И в модуле Panel
Код

procedure TPBZ.FormDestroy(Sender: TObject);  
begin
 Windows.SetParent(MSTask,MSTask_Parent);  //???
end;

Girder, извени что назадавал много вопросов, но просто у меня остался срок до текущей суботы, а чтобы самому, всё это разобрать нужно ...я даже не знаю сколько, но врядли управлюсь вовремя.

Но всётаки если ты мне на них ответиш, то я тебе буду очень признателен, и к тому же у меня уже скоро набежит 100 сообщений... smile

Заранее, благодарен, за неленивчивость!!! smile

Автор: Girder 17.11.2004, 11:23
Цитата(Zero @ 17.11.2004, 04:46)
Во первых как ты умудрился убрать строку
Цитата
WindowState:=wsMaximized
И при этом как-то экран всё равно увеличивается...
Перенес в OnActive
Цитата(Zero @ 17.11.2004, 04:46)
Потом процедура WndProc, это вообще просто тёмный лес
Стараемся не реагировать на попытку минимизации формы... smile
Цитата(Zero @ 17.11.2004, 04:46)
1─ый цикл
Находим первое верхнее окно
Цитата(Zero @ 17.11.2004, 04:46)
2─цикл
Ищем на верхнем уровне "Program Manager". Енто надежнее чем FindWindow... smile
Цитата
и зачем, ты их по умолчанию везде приравниваеш к нулю
Привычка... smile
Код
begin
 Tray_HWND:=findwindow('Shell_Traywnd',nil);  //Ищем "Панель задач"
 h:=findwindowex(Tray_HWND,0,'ReBarWindow32', nil); //Ищем дочернее окно-контейнер(Панель правее кнопки пуск) в панеле задач
 MSTask:=findwindowex(h,0,'MSTaskSwWClass', nil);  //Ищем в контейнере панель с минимизироваными окнами... :)
 Tray_Parent:=Windows.SetParent(Tray_HWND,pTray.Handle);  //Переопределяем родителя для Панели задач
 MSTask_Parent:=Windows.SetParent(MSTask,PBZ.Panel5.Handle);  //Минимизированные окна на Panel5(т.е. переопределяем родителя)
 pTray.Visible:=false;  //Скрываем панель задач
 Start:=true;
 Top:=0;
 Left:=0;
 Width:=Screen.Width;
 Height:=Screen.Height;
 Main_Desktop.SetFocus;
 Main_Desktop.Repaint;  //На всяк пожарный... :)
 PR_HWND_Def:=findwindowex(PR_HWND,0,'SHELLDLL_DefView',nil);  //Ищем в "Program Manager" контейнер
 if PR_HWND<>0 then Windows.SetParent(Handle,PR_HWND);  //Переопределяем родителя для главной формы, в данном случаи запихиваем главную форму в "Program Manager" и возлагаем всю работу по расположению главной формы на заднем плане на Explorer
 showwindow(PR_HWND_Def,SW_Hide);  //Скрываем контейнер в "Program Manager", что бы он(вслучаи чего) не перекрыл нашу форму
end;


Цитата(Zero @ 17.11.2004, 04:46)
Ещё, зачем нужна вот эта процедура, что она делает???

Цитата(Zero @ 17.11.2004, 04:46)
И в модуле Panel
Все наши издевательства над рабочим столом возвращают на круги своя... smile

PS: Перед применением SetParent, нужно еще стиль переопределяемого окна корректировать... но мне было лень енто добавлять. Все равно енто курсовой и препод и так ни чего не поймет... smile

Удачи.

Автор: Zero 17.11.2004, 11:55
Цитата
енто
Ошибочка... smile Енто --> пишется так "Это" Комодератор: Как слышится... так и пишется.. smile
Цитата
Все равно енто курсовой и препод и так ни чего не поймет...

Препод, тоже профессиональный программист smile , раз ты смог разобрасть в моём курсаче, то пред скорее всего тоже smile .
Спасибо, что вы с Послом самые не ленивые (ко)модераторы!!! smile
И спаибо тебе, огромно за помощь!!! Теперь кроме того что у меня всё хорошо стало работать, я ещё более менее разобрал некоторые вещи... smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)