2013-04-19 4 views
3

Как правильно определить код VBNET или C# для размера неклиентской зоны при активации Aero для COMPILED приложения? (Да, этой проблемы возникает только при запуске скомпилированного приложения, а не при запуске приложения из IDE)Как правильно определить размер области без клиента для Aero?

При изменении размера моей формы или я сделать любую операцию relationed с высотой/шириной вида I никогда не получите ожидаемого результата.

Например, это часть кода простого стыковке двух формах:

VB-NET:

Me.Location = New Point((form1.Location.X + form1.Width), form1.Location.Y) 

C#

this.Location = new Point((form1.Location.X + form1.Width), form1.Location.Y); 

К дайте пример, я покажу свою программу.

Код выше работает perfectlly когда Aero не активирован:

enter image description here

... Но если Aero активируется, то это результат:

enter image description here

Обратите внимание, как форма права находится под границей Неклиента левой формы.

... Или вот другое изображение, где левая форма находится под Non-Client границы правильной формы:

enter image description here

Мой вопрос Какой способ решить эту проблему?

UPDATE:

Расширение решения кадра не работает.

Form1:

Imports System.Runtime.InteropServices 

Public Class Form1 
    Public Moving_From_Secondary_Form As Boolean = False 

    <DllImport("dwmapi.dll")> _ 
    Private Shared Function DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef margins As MARGINS) As Integer 
    End Function 

    <StructLayout(LayoutKind.Sequential)> _ 
    Public Structure MARGINS 
     Public leftWidth As Integer 
     Public rightWidth As Integer 
     Public topHeight As Integer 
     Public bottomHeight As Integer 
    End Structure 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Dim margins As New MARGINS() 
     margins.leftWidth = -1 
     margins.rightWidth = -1 
     margins.topHeight = -1 
     margins.bottomHeight = -1 
     DwmExtendFrameIntoClientArea(Me.Handle, margins) 
     Form2.Show() 
    End Sub 

    Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move 
     If Not Moving_From_Secondary_Form Then Form2.Location = New Point(Me.Right, Me.Top) 
    End Sub 

End Class 

Form2:

Public Class Form2 

    Private Sub Form2_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move 
     Form1.Moving_From_Secondary_Form = True 
     Form1.Location = New Point(Me.Left - Form1.Width, Me.Top) 
     Form1.Moving_From_Secondary_Form = False 
    End Sub 

End Class 

Результат:

http://img824.imageshack.us/img824/3176/prtscrcapture2q.jpg

Также я хочу помнить: эта проблема возникает только при Runnin га компилируется приложение, а не при запуске приложения из IDE

**

UPDATE:

**

Испытано решение GetWindowRect и всегда возвращают 0, не работает для меня, может быть, я что-то делаю неправильно:

Imports System.Runtime.InteropServices 

Public Class Form1 

    Private Declare Function GetWindowRect Lib "user32" (ByVal Handle As IntPtr, Rect As RECT) As Long 
    Private Declare Function CopyRect Lib "user32" (DestRect As RECT, SourceRect As RECT) As Long 

    <StructLayout(LayoutKind.Sequential)> _ 
    Structure RECT 
     Public Left As Int32 
     Public Top As Int32 
     Public Right As Int32 
     Public Bottom As Int32 
    End Structure 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Form2.Show() 
    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     Dim rectWindow As RECT, rectCopy As RECT 

     'Get the bounding rectangle of this window 
     GetWindowRect(Me.Handle, rectWindow) 
     'Copy the rectangle 
     CopyRect(rectCopy, rectWindow) 

     MsgBox("This form's width:" & (rectCopy.Right - rectCopy.Left).ToString & " pixels") 
     Form2.Location = New Point(rectCopy.Right, rectCopy.Top) 
    End Sub 

End Class 

**

UPDATE:

**

Другой попробовать с GetWindowRect, на этот раз код правильно написал, но не решают проблему:

Imports System.Runtime.InteropServices 

Public Class Form1 
    <StructLayout(LayoutKind.Sequential)> _ 
    Private Structure RECT 
     Public Left As Int32 
     Public Top As Int32 
     Public Right As Int32 
     Public Bottom As Int32 
    End Structure 

    Private Declare Function GetWindowRect Lib "user32" (ByVal HWND As Integer, ByRef lpRect As RECT) As Integer 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     Dim rc As RECT 
     GetWindowRect(MyBase.Handle, rc) 
     Dim width As Integer = rc.Right - rc.Left 
     Form2.Show() 
     Form2.Location = New Point(rc.Right, rc.Top) 
    End Sub 

End Class 

enter image description here

Я хочу помнить: эта проблема возникает только при запуске скомпилированного приложения на Win7/Vista, а не при запуске приложения из IDE

ответ

2

Хотя я не проверял это лично вы можете расширить рамки в клиентской области с использованием DwmExtendFrameIntoClientArea и передачи -1.

Теоретически это должно означать, что указанный вами размер/позиции будет включать в себя кадр.

C# Подпись

[DllImport("dwmapi.dll", PreserveSig = true)] 
static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins); 

[DllImport("dwmapi.dll", PreserveSig = false)] 
static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins); 

VB.NET Подпись:

<DllImport("dwmapi.dll")> _ 
Private Shared Function DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef margins As MARGINS) As Integer 
End Sub 

Update

Вы думали о настройке формы стиля границы нет, и затем с помощью кнопка для контроля закрытия/минимизации е?Есть и другие варианты, которые могли бы получить результат ваш после тоже - FixedSingle и FixedToolWindow

Border Style

UPDATE 2

мне удалось воссоздать вашу проблему и решить ее с помощью следующего кода. Когда отладка позиции окна искажается, но при запуске скомпилированного exe расположение окна правильное.

Dim BorderWidth = (Me.Width - Me.ClientSize.Width) 
Me.Location = New Point((Form1.Location.X + (Form1.Width + BorderWidth)), Form1.Location.Y) 
+0

Спасибо, но это не решило проблему, увидеть мой обновленный вопрос, если вы можете. – ElektroStudios

+0

Похоже, вы только расширили рамку в форме1 - вы сделали это и для form2? – GJKH

+0

См. Обновленный ответ для другого предложения. – GJKH

2

Я не имею большого опыта работы с vb.net конкретно, но, как правило, я хотел бы использовать GetWindowRect(), чтобы получить полную внешнюю границу окна. По-видимому, будет доступна в vb.net

http://www.pinvoke.net/default.aspx/user32/getwindowrect.html

Сейчас нету б VB начиная с версии 6.0, но вы, возможно, придется преобразовать этот прямоугольник из пикселей в твипы.

Edit:

Этот код работает для меня:

Imports System.Runtime.InteropServices 

Public Class Form1 
    <StructLayout(LayoutKind.Sequential)> _ 
    Private Structure RECT 
     Public Left As Int32 
     Public Top As Int32 
     Public Right As Int32 
     Public Bottom As Int32 
    End Structure 

    Private Declare Function GetWindowRect Lib "user32" (ByVal HWND As Integer, ByRef lpRect As RECT) As Integer 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Dim rc As RECT 
     GetWindowRect(MyBase.Handle.ToInt32, rc) 

     Dim width As Integer = rc.Right - rc.Left 
     MessageBox.Show(width.ToString) 

    End Sub 
End Class 
+0

Спасибо, но я тестировал эту функцию Windows API и всегда возвращаю мне «0», только цифру 0. Можете ли вы опубликовать пример в VB6.0, чтобы получить размер формы ? – ElektroStudios

+0

Ваш код работает при запуске приложения из среды IDE, но не при запуске скомпилированного приложения по большому счету, я имею в виду, что если я попытаюсь найти форму2 со значениями RECT, это не решит проблему границы AERO. – ElektroStudios

+0

Плохо приглядывайся ... Но, кстати, вы пробовали SystemParametersInfo? – bitwise

0

Наконец я сделал это Snippet для Стыковка второстепенной формы справа от основного вида Wich работает, даже если Aero включен и если мы не запускаем отладку APP fom, Теперь мои приложения могут быть закреплены с поддержкой AERO на виртуальных машинах и всех (AERO) Windows: D.

' Instructions : 
    ' Change Manually the "StartPosition" property of "Form2" to "Manual", don't change it with code. 

    Public Moving_From_Secondary_Form As Boolean = False 

    ' Move Event Main Form 
    Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move 
     If Not Moving_From_Secondary_Form Then 
      If Debugger.IsAttached Then 
       Form2.Location = New Point(Me.Right, Me.Top) 
      Else 
       Form2.Location = New Point((Me.Location.X + (Me.Width + (Me.Width - Me.ClientSize.Width))), Me.Location.Y) 
      End If 
     End If 
    End Sub 

    ' Move Event Secondary Form 
    Private Sub Form2_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move 
     Form1.Moving_From_Secondary_Form = True 
     If Debugger.IsAttached Then 
      Form1.Location = New Point(Me.Left - Form1.Width, Me.Top) 
     Else 
      Form1.Location = New Point((Me.Location.X - (Form1.Width + (Form1.Width - Form1.ClientSize.Width))), Me.Location.Y) 
     End If 
     Form1.Moving_From_Secondary_Form = False 
    End Sub 

... А также эта функция:

#Region " Get Non-Client Area Width " 

    ' [ Get Non-Client Area Width Function ] 
    ' 
    ' Examples : 
    ' MsgBox(Get_NonClientArea_Width(Form1)) 
    ' Me.Location = New Point((Form1.Location.X + (Form1.Width + Get_NonClientArea_Width(Form1))), Form1.Location.Y) 

    Public Function Get_NonClientArea_Width(ByVal Form Form) As Int32 
     Return (Form.Width - Form.ClientSize.Width) 
    End Function 

#End Region 
+0

Что !? Почему вы не приняли моего ответа - вы используете мое решение выше, все, что вы сделали, помещено в оператор «if else», чтобы узнать, отлаживаетесь ли вы! – GJKH

+1

был извините – ElektroStudios

 Смежные вопросы

  • Нет связанных вопросов^_^