ايران ويج

نسخه‌ی کامل: مدیریت برنامه ی از قبل باز شده
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
صفحه‌ها: 1 2
فرض کنید که برنامه ی ما خودش رو به این شکل از حافظه خارج میکنه(البته برنامه اظهار میکنه که بسته شده، چون هنوز یک فرم (مثلا Form2 ) به طور مخفیانه در حال اجراست):
یعنی Form1 از حافظه خارج شده اما Form2 بدون ایکه کاربر ببینتش وجود داره:
CloseIt = FindWindow(vbNullString, "Form1")
PostMessage CloseIt, WM_CLOSE, CLng(0), CLng(0)

'Forme1 baste mishe(az hafeze kharej mishe), ama form2 ke visible-sh False-e vujud dare


**البته اینو بگم که واقعا نمیدونم که توسط این دستور فرم از حافظه خارج میشه یا نه، اما فرض میکنیم که از حافظه خارج میشه، چون درسته که برنامه رو End نمیکنه اما اگر فقط یک فرم داشته باشید و توسط دستور بالا ببندیدش عینا مثل دستور End عمل میکنه.

حالا
فرض کنید وقتی روی آیکن برنامه دوبار کلیک کردیم، برنامه میخواد بدون اینکه کاربر به چیزی شک کنه،
دوباره همون Form1 رو که توسط دستور بالا از حافظه خارج شد رو Load کنه.
من از دستورات زیر استفاده کردم(البته خیلی پیچیده تر از اینه، خیلی جاهاشو حذف کردم که مفهوم رو برسونم):

1. Dim ProgramIsRun As Long
2. ProgramIsRun = FindWindow(vbNullString, "Form1")

3. If (App.PrevInstance = True) Then 'agar barname Run bud (yani Form2 dar hale ejrast)
4. If ProgramIsRun = 0 Then 'agar Form1 Run Nabud
5. Call LoadSettings_Of_Registery
6. Form1.Show 'Form1 ro Run mikone
7. Else 'agar Form1 Run bud
8. End
9. Exit Sub
10. End If

مشکل در خط 6 میباشد، چرا که از همان فرم (Form1)، یک فرم جدید در حافظه لود میکند
(یعنی برنامه دوبار لود شده) برای این منظور میتونید Alt+Ctrl+Delete رو بزنید و در زبانه ی
Processes این جریان رو ببینید.(البته فرض بر این است که برنامه در زبانه ی Applications مخفی است)
ممکنه شما بگید:
خوب، Form1 رو با دستورات
CloseIt = FindWindow(vbNullString, "Form1")
PostMessage CloseIt, WM_CLOSE, CLng(0), CLng(0)
از حافظه خارج نکن و فقط ویزیبل رو فالس کن،
اما جواب من این است که: برنامه ی من میخواهد تظاهر کند که Exit شده (اما درواقع اینطور نیست)
همچنین آیکن برنامه ی من در system tray وجود دارد، و Hide کردن Form، یا Flase کردن visible، نمیتوانند کمکی به من بکنند.
بعد از این همه داستان سرایی،
میخواهم بدانم چکار کنم که همان فرم قبلی، که از حافظه خارج شده، دوباره به برنامه بازگردد، یعنی با دوبار کلیلک روی آیکن برنامه،برنامه ی جدیدی باز نشود و همان برنامه ای که از قبل باز هست را (Form2) مدیریت کرده و Form1 را (که قرار است در دید کاربر باشد) را لود کند.
اگه متوجه نشدید چی میگم برنامه ی زیر رو دانلود کنید:
اگه اینجا نوشته ها بهم ریخته ست، فایل متنی Tozihat رو دانلود کنید:
نقل قول: ...
بعد از این همه داستان سرایی،
باید فرمت رو هاید کنی و آیکن برنامه در سیستم ترای رو هم ببندی. به همین سادگی

در مورد بستن و بازگردوندن برنامه در ویندوز هم اگر مبانی سیستم عامل و پروسس ها رو مطالعه کنی متوجه

اشتباهت می شی، ولی در کل این کار رو با روش های خیلی پیچیده ای می شه انجام داد ولی اصلا به درد شما

نمی خوره.

Di Di جون نفهمیدم
میشه برناممو دانلود کنی و ببینیش؟
Di Di جون شی systray که ازش استفاده میکنم
قابلیت حذف آیکنش از systray رو مثه که نداره
میتونی برنامه رو نگاش کنی اگه داشت بهم بگو
نقل قول: شی systray که ازش استفاده میکنم
قابلیت حذف آیکنش از systray رو مثه که نداره

حتما داره ، بهتره از ورژن های بالاتر این کامپوننت که قبلا کرک کردم و داخل فروم قرار دادم استفاده کنی.
سلام.
شما میخوای به یه پروسه دیگه پیغام بفرستی.

یه راهش اینه که با دستور sendmessage و postmessage به پروسه دیگه کامند بفرستی.

یه راهش هم اینه که مثلا یه تکس باکس تو فرم2 قرار بدی. پروسه جدید که باز میشه هندل اون رو بگیره و با همون api های بالا مقدارش رو برابر تایم کنونی قرار بده. در ایونت textchange تکس باکست هم فرم1 رو فراخونی کنی.

یا راه ساده ترش اینه که هنگامی که پروسه جدید باز شد یه ولیو خاص در یه مسیر خاص رجیستری ایجاد کنه.
فرم 2 هم در یک تایمر وجود این ولیو رو چک کنه و در صورت مثبت بودن جواب پاکش کنه و فرم1 رو صدا بزنه.

یه راه ساده تر ترش هم اینه که کار بالا رو به وسیله ایجاد فایل انجام بدی.

اما سعی کن از تایمر استفاده نکنی و از روش اول یا دوم استفاده کنی.

برای آیکون system tray هم میتونی از Shell_NotifyIcon استفاده کنی که کنترلش دست خودته.
[quote='Di Di' pid='163824' dateline='1326803996']
نقل قول: حتما داره ، بهتره از ورژن های بالاتر این کامپوننت که قبلا کرک کردم و داخل فروم قرار دادم استفاده کنی.
Di Di جان میشه لینک بدی
Payman62 عزیز
خیلی ممنون از اینکه پاسخ دادید.
Shy Heart
ولی خیلی تخصصی صحبت کردین،Confused
سلام.
1 پروژه ویبی باز کن.
اسم فرمت رو بذار frmGetMessage. یه کلید به اسم cmdSendMessage و یه تکس باکس به اسم txtMessage روش قرار بده.

داخل فرم این کد رو قرار بده.

کد:
Private Sub Form_Load()
    gHW = Me.hwnd
    Hook
    Me.Caption = "Target"
    Me.Show
    lblHandle.Caption = "Handle: " & Hex$(gHW)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Unhook
End Sub

یه ماژول به پروژه اد کن و این کد رو داخلش قرار بده.

کد:
Private Type COPYDATASTRUCT
        dwData As Long
        cbData As Long
        lpData As Long
End Type

Public Const GWL_WNDPROC = (-4)
Public Const WM_COPYDATA = &H4A
Global lpPrevWndProc As Long
Global gHW As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Sub Hook()
    lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Private Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
   ByVal wParam As Long, ByVal lParam As Long) As Long
    If uMsg = WM_COPYDATA Then
        Call mySub(lParam)
    End If
    WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, _
       lParam)
End Function

Private Sub mySub(lParam As Long)
    Dim cds As COPYDATASTRUCT
    Dim buf(1 To 255) As Byte

    Call CopyMemory(cds, ByVal lParam, Len(cds))

    If cds.dwData = 3 Then
        CopyMemory buf(1), ByVal cds.lpData, cds.cbData
        a$ = StrConv(buf, vbUnicode)
        a$ = Left$(a$, InStr(1, a$, Chr$(0)) - 1)
        frmGetMessage.txtMessage.Text = a$
    End If
End Sub

Public Sub Unhook()
    Dim temp As Long
    temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub


یه پروژه جدید ویبی باز کن. اسم فرمت رو بذار frmSendMessage. یه کلید به نام cmdSendMessage و یه تکس باکس به اسم txtMessage داخلش قرار بده.
کد زیر رو داخل فرم بنویس.

کد:
Private Type COPYDATASTRUCT
        dwData As Long
        cbData As Long
        lpData As Long
End Type

Private Const WM_COPYDATA = &H4A

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

Private Sub Form_Load()
    Me.Caption = Hex$(FindWindow(vbNullString, "Target"))
End Sub

Private Sub cmdSendMessage_Click()
    Dim cds As COPYDATASTRUCT
    Dim ThWnd As Long
    Dim buf(1 To 255) As Byte

    ThWnd = FindWindow(vbNullString, "Target")
    a$ = txtMessage.Text
    
    CopyMemory buf(1), ByVal a$, Len(a$)
    cds.dwData = 3
    cds.cbData = Len(a$) + 1
    cds.lpData = VarPtr(buf(1))
    i = SendMessage(ThWnd, WM_COPYDATA, Me.hwnd, cds)
End Sub

حالا پروژه اول رو اجرا کن. بعد پروژه دوم رو اجرا کن. داخل تکس باکس پروژه دوم مقداری رو بنویس و روی کلید کلیک کن و نتیجه رو در تکس باکس پروژه اول مشاهده کن.
Payman62 جان
با این همه لطف شرمنده میکنی،
واقعا ممنونم ازت، کار کرد.
باید روش کار کنم ببینم واسه کاری که میخوام انجام بدم هم کار میکنه یا نه.
سلام.
چرا کار نکنه.
شما یه کپشن خاص مثلا به صورت GUID تولید کن که یونیک باشه. اون کپشن رو برای فرم 2ت قرار بده.
بعد هنگامی که برنامه دوباره اجرا شد و خواستی به برنامه قبلی بگی فرم 1 رو نشون بده با FindWindow و GUIDیی که برای فرم2 هست هندل فرم2 رو بگیر. بعد یه پیغام برای فرم 2 بفرست.
اون ور تو فرم 2 هم هنگامی که این پیغام رو دریافت کردی فرم1 رو نمایش بده.
صفحه‌ها: 1 2