| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > VB6 > программное размещение окон на экране |
| Автор: kb-nn 24.1.2005, 13:18 |
| кто- нибудь знает, как можно 2 файла, открытие с помощью ShellExecute, программно расположить на экране определенным образом?(например, чтобы 1-й файл занимал левую треть экрана, а второй- всю остальную часть?) |
| Автор: Naghual 24.1.2005, 14:54 |
| По идее - это возможно. Функция возвращает указатель на экземпляр приложения. Вот по нему можно получить указатель на окно. И екго уже разместить. Но все это - по идее. |
| Автор: ~FoX~ 24.1.2005, 15:32 |
| kb-nn А может тебе Split нужен? |
| Автор: kb-nn 24.1.2005, 15:35 |
| это как? сплит вроде разбивает строки? при чем он тут? |
| Автор: Naghual 24.1.2005, 16:03 |
| А еще, можно использовать FindWindow для получения окна. |
| Автор: kb-nn 24.1.2005, 16:20 |
| а подробнее можно? |
| Автор: Naghual 24.1.2005, 17:18 | ||
| Ну тогда начнем с конца. Чтобы задать размер/координаты окна, используется АПИ функция SetWindowPos:
Параметр, указывающий над каким окном производится действие - hwnd. Значит нам нужно получить этот hwnd. А тут возможны варианты. Напиши подробнее что и как ты запускаеш через ShellExecute. |
| Автор: kb-nn 25.1.2005, 10:01 |
| о! спасибо! на первый взгляд- понятно. |
| Автор: kb-nn 27.1.2005, 13:03 |
| слушайте, я открываю файл с помощью ShellExecute. потом использую SetWindowPos с полученным дескриптором. и от функции SetWindowPos никакого эффекта. что обозначают параметры hWndInsertAfter, wFlags у функции SetWindowPos ? |
| Автор: Naghual 27.1.2005, 13:06 | ||
А дескриптор ты откуда получил? |
| Автор: kb-nn 27.1.2005, 13:17 |
| из ShellExecute |
| Автор: Naghual 27.1.2005, 13:35 |
| А это не дескриптор hWnd! Это "... instance handle of the application that was run, or the handle of a dynamic data exchange (DDE) server application". А проще - это указатель на приложение (или сообщение об ошибке). Вот основной вопрос: Как из указателя приложения, получить дескриптор его окна. |
| Автор: kb-nn 27.1.2005, 15:48 |
| ну хорошо я пишу id=SelleExecute (...) myHWnd=FindWindow(0,id) SetWindowPos(myHWnd,0,0,0,400,500,1) и не работает |
| Автор: Naghual 27.1.2005, 16:21 |
| Не правильно. Потому и не работает. FindWindow ищет по заголовку окна, соответствующего классу (первый параметр). А вот как правильно - я пока не знаю. Буду думать. |
| Автор: Exception 2.2.2005, 15:18 | ||
| Запустили шелэкзекут, да? Потом:
Вот: купи Программирование в Win32 API на Visual Basic Дена Эпплмана. 500 руб, зато большинство винапи знаешь! |
| Автор: kb-nn 2.2.2005, 15:26 |
| но он неизвестен, вот в чем вопрос! Добавлено @ 15:33 известно только имя файла. Добавлено @ 15:34 кстати. спасибо за книжку. |
| Автор: Exception 2.2.2005, 15:55 |
| По моему была какаято апи функция для получения hwnd по process handle. Завтра напишу сегодня нет времени |
| Автор: kb-nn 2.2.2005, 15:59 |
| спасибо тебе |
| Автор: __Sergey__ 3.2.2005, 12:20 |
| Для запуска процесса используй CreateProcess. В возвращяемой структуре PROCESS_INFORMATION есть параметры, для ф-ции EnumThreadWindows. |
| Автор: Exception 3.2.2005, 18:33 | ||||
Точно!
dwThreadId - идентификатор нити. Потом с помощью EnumThreadWindows получаем список окон этой проги(их hwnd) и setwinpos Описание EnumThreadWindows:
lpfn - callback определенный через AddressOf Ну вощем дальше поймёшь. ЗЫ Книжка зовётся "Win32 API и Visual Basic" Дена Эпплмана. |
| Автор: kb-nn 4.2.2005, 14:35 |
| что- то я ничего не понял. |
| Автор: Exception 4.2.2005, 21:02 | ||
| Ты когда-нить AddressOf использовал? Смотри! Объявляешь структуру PROCESS_INFORMATION, таскаешь из нее dwThreadId (идентификатор нити). То есть процесс запускаешь не через ShellExecute а чрез CreateProcess(описание в win32api.txt) ну и все структуры там же. Поищи в MSDN CreateProcess. Так вот потом создаёшь модуль с функцией типа EnumThreadWindowsProc. Параметры не помню, порою. Потом из кода вызываешь EnumThreadWindows с парам.: dwThreadId - ид. нити lpfn - пишешь прямо в вызове AddressOf EnumThreadWindowsProc lparam оставляй 0. Например:
Для каждого окна этой нити( а у нас оно одно) Винды вызовут фнкцию EnumThreadWindowsProc написанною тобой. В вызове тебе и передадут hwnd. Вроде так: Public Function EnumThreadWindowsProc(ByVal hwnd as long, Byval lparam as long) As Long SetWindowPos(hwnd, и т.д....) 'Чтоб прервать перечисление возврати ноль. EnumThreadWindowsProc = 0 end Function Насчет описания ф-ции не уверен смотри MSDN. Добавлено @ 21:09 Короче завтра покопаюсь напишу код |
| Автор: Naghual 4.2.2005, 21:59 |
| Странно, но у меня не работает CreateProcess! Т.е. функция завершается успешно и даже имеется коекакая информация о процессе. Но вот запущенного приложения нет. Ни в исполняемых программах ни в процессах. Как-бы и не запустилось вовсе оно. Возможно я делаю что-то не так... |
| Автор: Exception 5.2.2005, 22:13 | ||
| Не знаю что у тебя не так, смотри мои параметры. Приведенный ниже код почти работает.ПОЧТИ. Трабл: при запуске управление передается другому процессу => не вызывается EnumThreadWindows. КСТАТИ: заметь, в объявлении КрэйтПроцесс я lpProcessAttributtes и lpThreadAttributes заменил типом Long и передаю 0. Код:
Подскажите, кто-нить, КАК ЗАПУСТИТЬ ПРОЦЕСС БЕЗ ПЕРЕДАЧИ УПРАВЛЕНИЯ. |
| Автор: kb-nn 7.2.2005, 15:23 |
| слушайте. вроде бы работает. спасибо! но неправильно отсчитываются координаты. нельзя ли сделать так, чтобы они были абсолютными, а не относительно дочернего окна? |
| Автор: __Sergey__ 7.2.2005, 19:46 |
| Используй ф-ции преобразования координат, сейчас точно нескажу, но примерно ClientToScreen and ScreenToClient |
| Автор: kb-nn 10.2.2005, 12:19 |
| ничего не получается. |
| Автор: Naghual 10.2.2005, 16:46 |
| Пересчитывай новое положение учитывая положение родительского окна |
| Автор: Exception 10.2.2005, 17:30 |
| Короче если выйдет перешли исходники мне на мыло pls. Всё равно считай отчасти это мои исходники |
| Автор: kb-nn 14.2.2005, 11:01 |
| дело в том, что я не очекнь понял функцию ClientToScreen. она берет координаты, и что дальше? а возвращает лишь успешен ли результат... я не понимаю... вы меня простите.... |
| Автор: Guest 14.2.2005, 15:08 |
| Возвращает (изменяет) в переданную тобой структуру POINT. |
| Автор: kb-nn 15.2.2005, 14:26 | ||
я делаю вот так
и при этом хочу, чтобы окно занимало две трети экрана |
| Автор: Naghual 15.2.2005, 14:36 |
| pa2.x = 2 * ((Screen.Width / Screen.TwipsPerPixelX) / 3) И не нужно никаких ClientToScreen |
| Автор: kb-nn 15.2.2005, 15:30 |
| не работает |
| Автор: Naghual 15.2.2005, 15:33 |
| Ну так и ЧТО не работает? |
| Автор: kb-nn 15.2.2005, 16:43 |
| ну не в том месте окно открывается. |
| Автор: Exception 15.2.2005, 16:55 |
| А ты проверь Pointapi. Может данные изменились. Функция берет твои коорд. а в той же переменной возвр screen |
| Автор: Гость___Sergey__ 15.2.2005, 17:15 |
| Когда я двигал оконца, то использовал вместо SetWindowPos, MoveWindow. С ней получалось. |
| Автор: Exception 15.2.2005, 18:49 | ||||
Простите 3ю страницу не заметил Добавлено @ 18:51
Вполне логично. В SetWPos есть парам. hwndInsertAfter а в moveWindow его нет. А нам он и не нужен |
| Автор: kb-nn 22.3.2005, 11:36 | ||
| слушайте, простите, ну почему у меня не работает.... Option Explicit Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long Public Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As _ Long) As Long Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _ ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long Public Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal _ lpCommandLine As String, lpProcessAttributes As Long, lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal _ dwCreationFlags As Long, lpEnvironment As Long, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long Public Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Public Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End Type Public Type POINTAPI x As Long y As Long End Type Sub Main() Dim OurThread As Long 'Íèòü çàïóùåííîãî ïðîöåññà Dim retval As Long 'Âîçâðàùàåìîå çíà÷åíèå Dim si As STARTUPINFO, pi As PROCESS_INFORMATION 'Ñòðóêòóðû si.cb = Len(si) Dim AppName As String 'Èìÿ ïðèëîæåíèÿ AppName = "C:\WINDOWS\EXPLORER.EXE" retval = CreateProcess(AppName, vbNullString, ByVal 0&, ByVal 0&, ByVal 0&, ByVal 0&, ByVal 0&, _ vbNullString, si, pi) 'Çàïóñêàåì ïðèëîæåíèå If retval = 0 Then Exit Sub 'Åñëè ïðîèçîøëà îøèáêà, âûõîäèì EnumThreadWindows pi.dwThreadId, AddressOf EnumFunc, ByVal 0& 'Ïåðåäà¸ì óêàçàòåëü íà EnumFunc Âèíäàì End Sub Public Function EnumFunc(ByVal hwnd As Long, ByVal lParam As Long) As Long Dim pa1 As POINTAPI Dim pa2 As POINTAPI pa1.x = 0 pa1.y = 0 pa2.x = 2 * ((Screen.Width / Screen.TwipsPerPixelX) / 3) pa2.y = Screen.Height '/ Screen.TwipsPerPixelY MoveWindow hwnd, pa1.x, pa1.y, pa2.x, pa2.y, True End Function Добавлено @ 11:37 вот, лучше так. извиняюсь. для удобства чтения
|
| Автор: kb-nn 22.3.2005, 12:18 |
| хочу, чтобы окно занимало левые две трети экрана. (и левый верх был в левом верхнем углу) |
| Автор: Guest 23.3.2005, 16:16 | ||||
| Попробуй передать необходимые параметры окна в STARTUPINFO, а потом CreateProcess. И я так подозреваю, не
а
|
| Автор: Guest 23.3.2005, 16:21 | ||
Или так
|
| Автор: kb-nn 23.3.2005, 16:35 | ||
| но окно открывается! только не в том месте. и в ширину оно занимает не 2/3, а больше так?
увы, всё тоже самое.... |
| Автор: Гость___Sergey__ 23.3.2005, 17:01 |
| Вставь до вызова EnumThreadWindows Sleep 1000, можеть меньше, может больше. Пробуй методом тыка. По моему окно не успевает создаться, а ты уже его энумить собрался |
| Автор: valex13 8.4.2005, 07:49 | ||||
| Можно воспользоваться универсальной функцией поиска окна. Она описана в MSDN Выкладываю:
А искать окно можно так:
Таким образом, ты можешь найти hWND обоих окон. В качестве параметра поиска окна по заголовку передай *FileName1 и *FileName2, а затем воспользуйся API функции для изменения размеров. Однако, для этого нужно знать размеры экрана. Расширение! |
| Автор: kb-nn 18.4.2005, 14:13 |
| что- то я ничего не понимаю. у меня вообще, как будто от функции MoveWindow толку не видно. что бы я ей не давал, она ничего не меняет... |
| Автор: Exception 19.4.2005, 11:06 | ||
| Ну ты попробуй с разными hwnd, эйчвинд вэбэ попробуй... Может и правда
|
| Автор: kb-nn 19.5.2005, 12:29 |
| что- то я не понял. что значит с разными hwnd? |
| Автор: Гость_Run-time Error 19.5.2005, 15:51 |
| Ну может у тебя конкретно с этим окном не выходит а с окном vb может выйти. тогда будешь знать, где ошибка |
| Автор: __Sergey__ 19.5.2005, 16:00 |
| Ну ты и растянул эту бадягу Я уже пробовал. Вставь Sleep, как я выше писал и расслабся. Добавлено @ 16:01 Со Sleep все работает |
| Автор: kb-nn 24.5.2005, 12:50 |
| со sleep у меня окно сворачивается через указанное время. |
| Автор: Exception 24.5.2005, 16:30 |
| __Sergey__, kb-nn, просто сраыните друг с другом свой код и все |
| Автор: kb-nn 5.5.2006, 17:20 | ||
| простите, я всё о своем, о наболевшем.... у меня начало работать, но SetWindowPos срабатывает не для всех файлов. (вручную для них размеры меняются и перемещаются без проблем) может у вас появится мысля- от чего это может зависеть?
|