none
程式縮至常駐列,程式重複開啟時視窗無法還原 RRS feed

  • 問題

  • 使用VB 2008 ,主程式裡加入了 NotifyIcon ,讓 Form 縮小時顯現  NotifyIcon,
    在專案-->屬性-->應用程式-->選取 建立單一執行個體應用程式 核取方塊,

    當程式縮小隱藏、 NotifyIcon 顯現在常駐列中,再執行主程式執行檔,製造重複開啟程式,
    滑鼠雙擊 NotifyIcon 讓程式自動還原到桌面顯示、 NotifyIcon 隱藏,此時將程式再次縮小隱藏、NotifyIcon 顯現在常駐列中,

    這樣的步驟重複2~3次後視窗會沒辦法正常還原到桌面了。

    另外有沒有辦法遇到重複執行程式時,直接將已執行的程式顯現的方式?

     Private Sub Form1_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
            If Me.WindowState = FormWindowState.Minimized Then
                NotifyIcon1.Visible = True
                Me.Hide()
            End If
        End Sub
        Private Sub NotifyIcon1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
            Me.Show()
            Me.WindowState = 0 '還原
            Me.Activate()
            Me.TopMost = True
            NotifyIcon1.Visible = False
        End Sub



    • 已編輯 C.Kevin 2013年2月2日 上午 01:51
    2013年2月2日 上午 01:29

解答

  • Hi,

    看不太懂你想表達的

    "當程式縮小隱藏、 NotifyIcon 顯現在常駐列中,再執行主程式執行檔,製造重複開啟程式,
    滑鼠雙擊 NotifyIcon 讓程式自動還原到桌面顯示"

    以你的程式來說,應該只有點NotifyIcon會讓視窗跑出來

    那...重複開啟程式的用意是?為何重複開啟程式後還要點NotifyIcon?你要的效果是甚麼看不太懂...

    如果你是要重複啟動程式時把以開啟的程式視窗帶出來

    我印象中"建立單一執行個體應用程式"這個選項並沒辦法幫你做到這個效果

    你必須要自己處理

    用Mutex去控制程式當偵測到已經開啟時

    發送sendmessage給舊的程式然後關閉

    舊的程式接收到訊息後把視窗帶出

    Reference

    http://www.dotblogs.com.tw/larrynung/archive/2012/04/08/71353.aspx

    http://www.dotblogs.com.tw/larrynung/archive/2012/11/26/85065.aspx


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    2013年2月2日 上午 02:16
  • Hi,

    我有實際拿你的程式碼片段來測試

    當問題發生時我有將Visual studio attach to process

    然後設定斷點來看

    發現視窗的位置被帶到-3200,-3200

    所以我才說看起來是位置與大小跑掉了

    今天再測了一次~發現當在我電腦縮小時位置就會跑到-3200,-3200

    不一定要問題發生才會跑到那邊

    但是問題發生時它位置會帶不回去

    這邊我用Mutex去實作一樣的效果就OK~

    看起來滿像是內建功能的問題

    最後這邊附上我的測試程式

    使用時要把屬性頁的Enable application framework關閉,然後startUp object要選sub main

    Imports System.Threading

    Public Class Form1

        <STAThread> _
        Public Shared Sub Main()
            Dim isCreated As Boolean

            Using m As New Mutex(False, "NotifyIconApp", isCreated)
                If Not isCreated Then
                    Return
                End If
                Application.Run(New Form1())
            End Using
        End Sub

        Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
            If Me.WindowState = FormWindowState.Minimized Then
                NotifyIcon1.Visible = True
                Me.Hide()
            End If
        End Sub

        Private Sub NotifyIcon1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
            Me.Visible = True
                Me.WindowState = 0 '還原
            Me.Activate()
            Me.TopMost = True
            NotifyIcon1.Visible = False
        End Sub
    End Class

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    • 已標示為解答 C.Kevin 2013年2月4日 上午 12:57
    2013年2月3日 下午 01:27

所有回覆

  • Hi,

    看不太懂你想表達的

    "當程式縮小隱藏、 NotifyIcon 顯現在常駐列中,再執行主程式執行檔,製造重複開啟程式,
    滑鼠雙擊 NotifyIcon 讓程式自動還原到桌面顯示"

    以你的程式來說,應該只有點NotifyIcon會讓視窗跑出來

    那...重複開啟程式的用意是?為何重複開啟程式後還要點NotifyIcon?你要的效果是甚麼看不太懂...

    如果你是要重複啟動程式時把以開啟的程式視窗帶出來

    我印象中"建立單一執行個體應用程式"這個選項並沒辦法幫你做到這個效果

    你必須要自己處理

    用Mutex去控制程式當偵測到已經開啟時

    發送sendmessage給舊的程式然後關閉

    舊的程式接收到訊息後把視窗帶出

    Reference

    http://www.dotblogs.com.tw/larrynung/archive/2012/04/08/71353.aspx

    http://www.dotblogs.com.tw/larrynung/archive/2012/11/26/85065.aspx


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    2013年2月2日 上午 02:16
  • 謝謝蹂躪大大的解說,幾乎快解答完問題了,
    [ 用Mutex去控制程式當偵測到已經開啟時,發送sendmessage給舊的程式然後關閉,舊的程式接收到訊息後把視窗帶出],
    這個我去找資料實做。

    因為我想做禁止重複開啟程式的功能,但我在程式中放了NotifyIcon ,NotifyIcon.Visible = False
    在專案-->屬性-->應用程式-->選取 建立單一執行個體應用程式 核取方塊,
    然後執行程式執行檔,程式啟動後將 Form 縮小,然後

        Private Sub Form1_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
            If Me.WindowState = FormWindowState.Minimized Then
                NotifyIcon1.Visible = True
                Me.Hide()
            End If
        End Sub

    這時再執行一次程式執行檔,製造重複開啟程式的情況,
    第二個程式不會啟動,
    到常駐列中手動雙擊 NotifyIcon 將視窗還原,這裡模擬使用者發現程式已被開啟而去常駐列找程式,

        Private Sub NotifyIcon1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
            Me.Show()
            Me.WindowState = 0 '還原
            Me.Activate()
            Me.TopMost = True
            NotifyIcon1.Visible = False
        End Sub

    程式用著用著使用者再度將視窗縮小,觸發 Form1_Resize,
    然後使用者忘記程式已被打開,觸發 NotifyIcon1_MouseDoubleClick,
    使用者再度將視窗縮小............觸發 Form1_Resize.................
    以這樣的步驟重複2~3次後會發生 NotifyIcon1_MouseDoubleClick 事件將視窗回復會失效,
    想問問看該怎麼處理這樣。

     

    2013年2月2日 上午 03:23
  • Hi,

    如果是這樣...

    我試了一下~看起來是location跟size會跑掉

    你想辦法把它設回來就可以了


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    2013年2月2日 上午 03:45
  • 我在  NotifyIcon1_MouseDoubleClick 加入了 Location 和 Size 的設定,還有些些不太靈光,
    開始出現視窗回覆失效後,在下方工具列右鍵點選該程式最小化,再從常駐列雙擊 NotifyIcon 回復視窗,
    再縮小視窗,回復視窗~~~經過這一輪的步驟才會正常顯示設定的 Locatrion 和 Size。

    請問蹂躪大大是怎麼推測出 Location 和 Size 跑掉的?

    2013年2月2日 上午 06:16
  • Hi,

    我有實際拿你的程式碼片段來測試

    當問題發生時我有將Visual studio attach to process

    然後設定斷點來看

    發現視窗的位置被帶到-3200,-3200

    所以我才說看起來是位置與大小跑掉了

    今天再測了一次~發現當在我電腦縮小時位置就會跑到-3200,-3200

    不一定要問題發生才會跑到那邊

    但是問題發生時它位置會帶不回去

    這邊我用Mutex去實作一樣的效果就OK~

    看起來滿像是內建功能的問題

    最後這邊附上我的測試程式

    使用時要把屬性頁的Enable application framework關閉,然後startUp object要選sub main

    Imports System.Threading

    Public Class Form1

        <STAThread> _
        Public Shared Sub Main()
            Dim isCreated As Boolean

            Using m As New Mutex(False, "NotifyIconApp", isCreated)
                If Not isCreated Then
                    Return
                End If
                Application.Run(New Form1())
            End Using
        End Sub

        Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
            If Me.WindowState = FormWindowState.Minimized Then
                NotifyIcon1.Visible = True
                Me.Hide()
            End If
        End Sub

        Private Sub NotifyIcon1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
            Me.Visible = True
                Me.WindowState = 0 '還原
            Me.Activate()
            Me.TopMost = True
            NotifyIcon1.Visible = False
        End Sub
    End Class

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    • 已標示為解答 C.Kevin 2013年2月4日 上午 12:57
    2013年2月3日 下午 01:27