View Full Version : سوال: فعال کردن پنجره
ASedJavad
دوشنبه 15 اسفند 1390, 23:47 عصر
سلام
ميخوام وقتي برنامم رو اجرا ميکنم، پنجره اي که قبل از اجراي برنامم فعال بوده، دوباره بلافاصله فعال شه.
توضيح: برنامم هيچ فرم وکنترلي نداره و يه sub main سادست. در ضمن قراره تو ويندوز برا برنامم يه کليد ميانبر تعريف کنم که تو هر پنجره اي کاربر اون کليد ميانبرو زد، برنامه اجرا بشه، رو پنجره فعال يه اعمالي انجام بده و بسته بشه
just4froum
سه شنبه 16 اسفند 1390, 00:44 صبح
کد مقابل را امتحان کنید :
Private Sub Form_Paint()
SendKeys "%{tab}"
End Sub
ASedJavad
سه شنبه 16 اسفند 1390, 01:12 صبح
نه
جواب نمیده!
just4froum
سه شنبه 16 اسفند 1390, 01:26 صبح
آخه Alt + Tab بین دو برنامه آخر تعویض میکنه (اگر یکبار بزنیم)
یک سوال : برنامه شما اجرا هستش و می خواید هر وقت کاربر کلید میانبر را زد پنجره قبلی فکوس بگیرد یا نه اصلا برنامه اجرا نیست ؟
ASedJavad
سه شنبه 16 اسفند 1390, 01:36 صبح
نه اجرا نیست
با کلید میانبر اجرا میشه
just4froum
سه شنبه 16 اسفند 1390, 01:55 صبح
نه اجرا نیست
با کلید میانبر اجرا میشه
منظورم اینه که توی لیست پروسس های تسک منیجر هست یا نه (Tray یا Minimized)
اگر اجرا نیست شما این کلید میانبر را از Properties برنامه بهش میدین ؟
ASedJavad
سه شنبه 16 اسفند 1390, 02:34 صبح
نه
یه شرت کات از فایل اگزش میسازم
تو مشخصات شرتکات یه گزینه داره به اسم shortcut key
از اونجا براش شرتکات تعریف میکنم
Mr'Jamshidy
سه شنبه 16 اسفند 1390, 15:12 عصر
اگر فرم نداری در اول برنامه تابع GetActiveWindow رو اجرا کن ببین هندل پنجره مورد نظرت رو بر میگردونه یا نه بعد با SetFocus به پنجره فوکاس بده ببین چی میشه
Declare Function SetFocus Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long
Declare Function GetActiveWindow Lib "user32" Alias "GetActiveWindow" () As Long
quiet_programmer
سه شنبه 16 اسفند 1390, 16:21 عصر
با سلام.
ميخوام وقتي برنامم رو اجرا ميکنم، پنجره اي که قبل از اجراي برنامم فعال بوده، دوباره بلافاصله فعال شه.
یه همچین چیزی مگه میشه؟ وقتی شما داری برنامه رو اجرا میکنی خوب معلومه که میری رو فایل دابل کلیک میکنی در این لحظه هیچ پنجره ای فعال نیست. اگه منظورت قبل اجرای برنامه باشه، انوقت بازهم نمیشه. باید یه برنامه دیگه باشه که هندل پنجره های دارای فوکوس رو لاگ کنه. بعد اجرای برنامه بیاد از لاگها استفاده کنه و توسط تابع api مربوطه که جناب Mr'Jamshidy (http://barnamenevis.org/member.php?43330-Mr-Jamshidy) گذاشتن فوکوس رو بدی به پنجره. ولی اگه قراره برنامه به صورت نرم افزاری اجرا بشه با توجه به این برنامه دارای فرم نیست انگار که هیچ اجرایی صورت نگرفته و اجرای برنامه بر روی پنجره دارای فوکوس هیچ تاثیر نخواهد گذاشت.
یا حق.
همیشه موفق باشید/
ASedJavad
سه شنبه 16 اسفند 1390, 21:44 عصر
اگر فرم نداری در اول برنامه تابع GetActiveWindow رو اجرا کن ببین هندل پنجره مورد نظرت رو بر میگردونه یا نه بعد با SetFocus به پنجره فوکاس بده ببین چی میشه
نه متاسفانه
نه با این تابع هندل بدست میاد نه با getForgroundWindow
یه همچین چیزی مگه میشه؟ وقتی شما داری برنامه رو اجرا میکنی خوب معلومه که میری رو فایل دابل کلیک میکنی در این لحظه هیچ پنجره ای فعال نیست. اگه منظورت قبل اجرای برنامه باشه، انوقت بازهم نمیشه. باید یه برنامه دیگه باشه که هندل پنجره های دارای فوکوس رو لاگ کنه. بعد اجرای برنامه بیاد از لاگها استفاده کنه و توسط تابع api مربوطه که جناب Mr'Jamshidy (http://barnamenevis.org/member.php?43330-Mr-Jamshidy) گذاشتن فوکوس رو بدی به پنجره.
سلام
گفتم که قرار نیست رو فایل اگزه دابل کلیک کنم. بلکه یه shortkey برا برنامه قرار میدم که با استفاده از صفحه کلیک فایل اگزه اجرا بشه.
شما فرض کن تو فایرفاکس داری کار میکنی بعد shift + f1 رو میزنی و برنامه اجرا میشه ولی فوکوس از رو فایرفاکس برداشته میشه. حالا من میخوام فوکوس دوباره برگرده رو فایرفاکس.
اگه قراره برنامه به صورت نرم افزاری اجرا بشه با توجه به این برنامه دارای فرم نیست انگار که هیچ اجرایی صورت نگرفته و اجرای برنامه بر روی پنجره دارای فوکوس هیچ تاثیر نخواهد گذاشت.
اتفاقا چرا
با اینکه برنامه دارای فرم نیست ولی وقتی برنامه ران میشه فوکوس از رو برنامه قبلی میره!
ASedJavad
جمعه 19 اسفند 1390, 16:54 عصر
ظاهرا این سوال رو هم باید به خیل سوالای بی جواب مونده من اضافه کرد!
just4froum
جمعه 19 اسفند 1390, 21:59 عصر
با سلام :
من راه های زیادی رو امتحان کردم اما تنها راهی که جواب داد این بود که یک پروزه دیگه ساختم با یک فرم و توی روال Form_Paint نوشتم :
sendkeys "%{tab}"
doevents
end
و با پروزه اصلیم با Shell اجراش کردم و درست کار کرد ولی بدون فرم هر کاری کردم نشد.
setroyd
شنبه 20 اسفند 1390, 00:29 صبح
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
با این دو تابع میتونی اخه شما سعی نمیکنید فقط میگید نمیشه !!!! شما برنامه ای که میخوای خیلی راحت میشه با این 2 api نوشت .
ASedJavad
شنبه 20 اسفند 1390, 00:34 صبح
نه اتفاقا
من قبل از این که این تاپیک رو بزنم اول خودم امتحان کردم اینا رو.
مشکل اینه که ظاهرا باید پنجره مورد نظرمون همون forground window باشه، ولی نیست.
البته فکر کنم با findwindowex باید بشه هندلشو پیدا کرد
ولی هنوز که نتونستم.
setroyd
شنبه 20 اسفند 1390, 00:48 صبح
یه توضیح کامل بده از برنامت که میخوای من بفهمم کامل منظورتو ؟؟؟ کامل توضیح بده مو به مو ؟
ASedJavad
شنبه 20 اسفند 1390, 01:00 صبح
برنامه فقط یه مدول داره که توش یه تابع main داره (بدون هیچ فرم و کنترلی و هیچ کار گرافیکی خاصی)
پس طبیعتا وقتی برنامه ران بشه، تابع main اجرا میشخ و بعد برنامه به پایان رسیده و بسته میشه.
حالا من میام از فایل اگزش یه شرتکات میسازم و را شرتکاتش از طریق ویندوز یه شرتکی قرار میدم مثلا shift + f1
حالا فرض کن من دارم با فایرفاکس کار میکنم بعد لازمم میشه برنامم رو اجرا کنم
پس تو همون فایرفاکس shift + f1 رو میگیرم ، برنامه ران میشه و بسته میشه و مشکلی که این وسط پیش میاد اینه که دیگه در این موقع فایرفاکس پنجره فعالمون نیست.
setroyd
شنبه 20 اسفند 1390, 04:04 صبح
میشه درست کردتش فردا سعی میکنم مشکلتو حل کنم . اخه تا حالا این کارو نکردم و نمیدونم میشه در اوردتش یا نه !
setroyd
شنبه 20 اسفند 1390, 12:02 عصر
من نوشتم برنامه رو مشکلی نداشت سورست رو بزار ببینم مشکلش چیه تا دوباره برات ضمیمه کنم ؟
ASedJavad
شنبه 20 اسفند 1390, 13:42 عصر
سورس خاصی نیست
اصلا شما فرض کن سورسش اینه:
ُSub Main()
end
End Sub
ممنون میشم شما همون چیزی رو که میگید نوشتید بذارید.
setroyd
شنبه 20 اسفند 1390, 14:02 عصر
با این مشکلی نیست چون من این رو امتحان کردم شد .
مگر اینکه شما در سورست از api های خاصی استفاده کرده باشین .
ASedJavad
شنبه 20 اسفند 1390, 19:43 عصر
یعنی شما وقتی یه فایل اگزه با این سورس رو که گذشتم از طریق شرت کی اجرا میکنین، فوکوس رو همون نرم افزار قبلی باقی می مونه؟!:متفکر:
setroyd
یک شنبه 21 اسفند 1390, 11:02 صبح
اره عزیز من واسه همین گفتم سورس رو بزار ببینم مشکلش چیه .
ASedJavad
یک شنبه 21 اسفند 1390, 14:52 عصر
سلام
ممنون از اینکه برا حل مشکل من وقت میذارید
یک گزارش تصویری لحظه به لحظه از روند کار براتون ضمیمه میکنم.
شاید یه فوت کوزه گری داره که من نمیدونم؟!
محسن واژدی
جمعه 26 اسفند 1390, 09:50 صبح
سلام
شاید اشتباه از بنده باشد، ولی تاکنون ندیده ام وقتی برنامه ای اجرا میشود فوکوس بر روی برنامه قبلی مانده باشد حتی اگر از میانبر در دسکتاپ استفاده کرده باشیم، بهرحال در اولین اجرا فوکوس از روی پنجره فعلی پرش میکند به برنامه اجرا شده، این مورد حتی در OSKeyboard ویندوز هم مستثنی نیست، البته با کدی مشابه زیر برنامه میتواند تا حدودی شبیه OSK رفتار کند، ولی همانطور که در ابتدا هم عرض کردم در ابتدای اجرا فوکوس بر روی برنامه پرش میکند که در اینصورت برنامه اجرا شده میشود جلوترین برنامه که در این حالت، دستوراتی مانند GetForgroundWindow و مانند اینها نیز عملا بلااستفاده میشوند:
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const GWL_EXSTYLE As Long = -20
Private Const WS_EX_NOACTIVATE As Long = &H8000000
Private Sub Form_Initialize()
Call SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_NOACTIVATE)
End Sub
موفق باشید
ASedJavad
جمعه 26 اسفند 1390, 10:31 صبح
سلام
شاید اشتباه از بنده باشد، ولی تاکنون ندیده ام وقتی برنامه ای اجرا میشود فوکوس بر روی برنامه قبلی مانده باشد حتی اگر از میانبر در دسکتاپ استفاده کرده باشیم، بهرحال در اولین اجرا فوکوس از روی پنجره فعلی پرش میکند به برنامه اجرا شده، این مورد حتی در OSKeyboard ویندوز هم مستثنی نیست، البته با کدی مشابه زیر برنامه میتواند تا حدودی شبیه OSK رفتار کند، ولی همانطور که در ابتدا هم عرض کردم در ابتدای اجرا فوکوس بر روی برنامه پرش میکند که در اینصورت برنامه اجرا شده میشود جلوترین برنامه که در این حالت، دستوراتی مانند GetForgroundWindow و مانند اینها نیز عملا بلااستفاده میشوند
سلام
خیلی مهم نیست که فوکوس نمونه رو پنجره قبلی، بلکه مهم برام اینه که بلافاصله بعد از اجرای برنامه، فوکوس رو برگردونیم رو برنامه قبلی.
ولی این کدی که شما دادید، فوکوس رو منتقل میکنه به تسکبار ویندوز، نه به برنامه قبلی
(این حالت وقتی روی میده که برای اجرای برنامه از شرتکی استفاده کنیم)
نمونه چیزی که من میخوام هم اینجا دیدم:
http://aftab.cc/article/902
Veteran
جمعه 26 اسفند 1390, 12:25 عصر
خب...........
به صورت معمولی روی ویندوز ایکس پی مشکلی نداره.. فوکس میمونه . از روی پنجره نمیپره
اما روی ویندوز سون چرا از روی پنجره فوکس میره
حالا شما میخواین این فوکس از دست رفته رو برگردونید.
اگر توی ویندوز سون کلید های Alt+tab رو فشار بدید یک لیستی میاد که اولین برنامه از سمت چپ برنامه ای هست که در حال حاضر فوکس روی اون قرار داره مثلا الان ماله من فایرفاکس هست چراه که دارم این متن رو مینوسیم بعد دومین برنامه از سمت چپ برنامه قبلی هست که اجرا شده.
اگر من الان بخوان که از پنچره فایرفاکس بخوام برم به پنجره قبلی کافیه که alt+tab بگیرم بعد بلافاصله tab رو رها و بعد alt رو رها بکنم.
حالا میخوایم این روش رو با vb6 پیاده سازی بکنیم
ی api یمخوایم برای انجام کلید های کیبورد
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
ثابت های alt و tab رو میخوایم.
Private Const VK_ALT = &H12
Private Const VK_TAB = &H9
چون باید کلید هارو هم رها بکنیم باید از ثابت
Private Const KEYEVENTF_KEYUP = &H2
استفاده بکنیم.
حالا میخوایم که اون لیست برنامه های در حال اجرا که خودمون به وسیله alt+tab میاوردیم رو با وی بی بیاریم
خب باید از ثابت ها استفاده کنیم
keybd_event VK_ALT, 0, 0, 0
keybd_event VK_TAB, 1, 0, 0
الان اگر تا اینجای کار رو اجرا کنیم میبینیم که ما تونستیم لیست رو بیاریم.
اما چون هنوز ما عمل رها کردم رو انجام ندادیم لیست میمونه و نمیره
باید کلید tab رو رها کنیم چرا که اگر اول alt رو رها کنیم ممکنه در پنجره یک سری دستور ایجرا کنه مثلا اگر پنجره قبلی ما نودپد باشه اگر اول alt رو رها کنیم به نودپد میره اما چون هنوز
tab رو رها نکردیم توی نودپد فاصله(فضا خالی) ایجاد میکنه
پس اول tab
از ثابت رها کردن استفاده میکنیم
keybd_event VK_TAB, 0, KEYEVENTF_KEYUP, 0
بعد alt
keybd_event VK_ALT, 0, KEYEVENTF_KEYUP, 0
این چندتا ثابت دیگه
Const VK_SHIFT = &H10
Const VK_LEFT = &H25
Const VK_RIGHT = &H27
Const VK_UP = &H26
Const VK_DOWN = &H28
فکر کنم با این توضیحات بشه این چیزی که شما میخوای رو انجام داد من خودم نتونستم تست کنم تا ببینم میشه یا نه اینارو داشتم از قبل توی ی فایل گفتم شاید به درد بخوره
شما تست کنین مشکلی داشت بگین
ASedJavad
جمعه 26 اسفند 1390, 12:41 عصر
به صورت معمولی روی ویندوز ایکس پی مشکلی نداره.. فوکس میمونه . از روی پنجره نمیپره
مطمئنید؟ خودتون تو xp تست کردین؟
یعنی هر چی میکشیم از دست سونه؟
شما تست کنین مشکلی داشت بگین
میدونید چیه؟
مشکل اینجاست که وقتی برنامه رو با شرتکیش فراخونی میکنیم، برنامه فعال قبلی میره به آخر لیست برنامه های alt + tab
(نمیدونم متوجه شدید چی میگم؟)
یعنی باید بیایم اول تعداد اون برنامه ها رو در بیاریم بعد به تعداد اونها tab بزنیم.
نمیدونم اصلا این کار شدنیه یا نه!
ولی اگر هم بشه، مسلما چیز چندان جالبی نمیشه!
_____________________
پ.ن
اصلا حواسم به alt + shift + tab نبود.
باید بررسیش کنم ببینم جواب میده یا نه!
Veteran
جمعه 26 اسفند 1390, 17:10 عصر
مطمئنید؟ خودتون تو xp تست کردین؟
یعنی هر چی میکشیم از دست سونه؟من روی سیستمم هم سون دارم هم ایکس پی.
روی ایکس پی که وقتی برنمه رو اجرا کردم فوکس از روی پنجزه نرفت و موند.
====
م
شکل اینجاست که وقتی برنامه رو با شرتکیش فراخونی میکنیم، برنامه فعال قبلی میره به آخر لیست برنامه های alt + tab
(نمیدونم متوجه شدید چی میگم؟)چرا که برنامه شما اصلا فرم نداره و اصلا در اون لیست قرار نمیگیره. شما برای برنامه فرم بزارید.
من خودم با ویندوز تست کردم یک فرم خالی درست کردم . exe گرفتم.
بعد نودپد رو باز کردم بعدش برنامه رو اجرا کردم.
فوکس میره روی برنامه.
پس برنامه میشه اولین گزینه از سمت چپ و برنامه قبلی یعنی نودپد شده بود دومین گزینه اس سمت چپ
این رو تست کنین ببینید جواب میده یا نه
============
ی ره دیگه :
اگر میره به اخرین گزینه باید این کارو کرد
شما وقتی alt+tab رو میزنید بلافاصله tab رو که رها میکنید روی گزینه دوم قرار مییره حالا واسه اینکه ما بیایم به گزینه اخر باید 2 گزینه به سمت چپ حرکت کنیم.
یکی برای اومدن به اولین گزینه یکی برای اومدن به اخرین گزینه.
از ثابت
Private Const VK_LEFT = &H25
استفاده میکنیم.
خب حالا بعد از اوردن اون لیست شما باید این کد رو دوبار اجرا کنیم کد زیر یکی برای اومدن به اولین گزینه یکی برای اومدن به اخرین گزینه.
keybd_event VK_LEFT, 1, 0, 0
این رو هم تست کنین
البته باید بعد از اجرا
VB]keybd_event VK_LEFT, 1, 0, 0[/VB]
هم رها کنید
===========
xxxxx_xxxxx
جمعه 26 اسفند 1390, 21:12 عصر
سلام،
روی سیستمم VB ندارم که تست کنم. اما ببینید میشه از تابع SetWindowPos نتیجه گرفت:
Private 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
این تابع میتونه کارهای زیادی روی یک پنجره انجام بده.
هفت تا پارامتر داره که شما فقط از پارامتر های اول و دوم و هفتم استفاده کنید. (چهار پارامتر x, y, cx, cy برای تعیین موقعیت جدید پنجره هست که برای این کار باید 0 گذاشته بشه)
پارامتر اول مشخصه که handle پنجره مورد نظر هست که برای اونم باید از تابع GetForegroundWindow در اول برنامه تون استفاده کنید تا هندل آخرین پنجره فعال رو بهتون بده.
پارامتر دوم (hWndInsertAfter) و هفتم (wFlags) مهم هستند که توضیحاتش رو از این صفحه (http://www.ex-designz.net/apidetail.asp?api_id=192) میزارم:
hWndInsertAfter
Either the handle of the window to position this window behind, or exactly one of the following flags stating where in the
Z-order to put the window:
HWND_BOTTOM = 1
Put the window at the bottom of the Z-order.
HWND_NOTOPMOST = -2
Put the window below all topmost windows and above all non-topmost windows.
HWND_TOP = 0
Put the window at the top of the Z-order.
HWND_TOPMOST = -1
wFlags
Zero or more of the following flags stating how to move the window:
SWP_DRAWFRAME = &H20
Same as SWP_FRAMECHANGED.
SWP_FRAMECHANGED = &H20
Fully redraw the window in its new position.
SWP_HIDEWINDOW = &H80
Hide the window from the screen.
SWP_NOACTIVATE = &H10
Do not make the window active after moving it unless it was already the active window.
SWP_NOCOPYBITS = &H100
Do not redraw anything drawn on the window after it is moved.
SWP_NOMOVE = &H2
Do not move the window.
SWP_NOSIZE = &H1
Do not resize the window.
SWP_NOREDRAW = &H8
Do not remove the image of the window in its former position, effectively leaving a ghost image on the screen.
SWP_NOZORDER = &H4
Do not change the window's position in the Z-order.
SWP_SHOWWINDOW = &H40
Show the window if it is hidden.
من چون روی سیستمم VB نصب ندارم نمیتونم تست کنم ولی فکر میکنم با قرار دادن مقدار 0 یا -1 برای پارامتر دوم و مقدار &H40 برای پارامتر هفتم بتونبد نتیجه مطلوب رو بگیرید.
فراخوانی این تابع، آخرین دستور برنامتون باشه.
فراخوانی تابع GetForegroundWindow هم اولین دستور برنامه تون باشه.
موفق باشید/
alipoor2009
چهارشنبه 02 فروردین 1391, 23:24 عصر
سلام - سال نو شما مبارک
این خیلی کار راحتی است و نیاز به تابع هم نداره
فرمی که می خواهید فعال بشه (البته تو برنامه ی خودتون) در رویداد Active فرم کد مقابل رو قرار بده -- اگه خواسته باشی فرم 2 رو نمایش بدی این کد را باید توی رویدار Active فرم 2 قرار بدی
Me.SetFocus
امیدوارم به جوابتون رسیده باشید
همیشه بهترین را کوتاه ترین راه است
موفق باشید
ASedJavad
سه شنبه 22 فروردین 1391, 01:03 صبح
ی api یمخوایم برای انجام کلید های کیبورد
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
عزیز! پارامتر دوم این تابع چیه؟
شما بعضی جاها یک بهش دادی و بعضی جا ها صفر.
چرا؟
محسن واژدی
سه شنبه 22 فروردین 1391, 18:32 عصر
سلام
احتمالا" در نمونه زیر مشکل پرش به پنجره قبلی برطرف شده باشد (اگر توجه کرده باشیم هنگام minimize شدن فرم فعلی ویندوز فوکوس را به فرم قبلی برمیگرداند که در اینصورت میتوانیم با یک ترفند فوکوس پنجره قبلی را بدست بیاریم)
موفق باشید
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.