3
WinForms에서 Magnification API를 사용하여 웹에서 library을 발견했습니다. 나는 WPF와 함께 작동하도록 만들었지 만, 아무런 예외 나 예외도 없었습니다. 모든 것이 OK 인 것 같습니다. 나는 이것이 WPF로 작동하지 않는다고 생각하기 시작했습니다.WinForms에서 WPF까지의 확대 API 사용
윈폼 번호 :
public class Magnifier : IDisposable
{
private Window window;
private IntPtr hwnd;
private IntPtr hwndMag;
private float magnification;
private bool initialized;
private RECT magWindowRect = new RECT();
private DispatcherTimer timer;
public Magnifier(Window window)
{
if (window == null)
throw new ArgumentNullException("form");
hwnd = new WindowInteropHelper(window).Handle;
magnification = 2.0f;
this.window = window;
this.window.SizeChanged += form_Resize;
this.window.Closing += form_FormClosing;
timer = new DispatcherTimer();
timer.Tick += timer_Tick;
initialized = NativeMethods.MagInitialize();
if (initialized)
{
SetupMagnifier();
timer.Interval = TimeSpan.FromMilliseconds(NativeMethods.USER_TIMER_MINIMUM);
timer.IsEnabled = true;
}
}
void form_FormClosing(object sender, CancelEventArgs e)
{
timer.IsEnabled = false;
}
void timer_Tick(object sender, EventArgs e)
{
UpdateMaginifier();
}
void form_Resize(object sender, RoutedEventArgs e)
{
ResizeMagnifier();
}
~Magnifier()
{
Dispose(false);
}
protected virtual void ResizeMagnifier()
{
if (initialized && (hwndMag != IntPtr.Zero))
{
NativeMethods.GetClientRect(hwnd, ref magWindowRect);
// Resize the control to fill the window.
NativeMethods.SetWindowPos(hwndMag, IntPtr.Zero,
magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, 0);
}
}
public virtual void UpdateMaginifier()
{
if ((!initialized) || (hwndMag == IntPtr.Zero))
return;
POINT mousePoint = new POINT();
RECT sourceRect = new RECT();
NativeMethods.GetCursorPos(ref mousePoint);
int width = (int)((magWindowRect.right - magWindowRect.left)/magnification);
int height = (int)((magWindowRect.bottom - magWindowRect.top)/magnification);
sourceRect.left = mousePoint.x - width/2;
sourceRect.top = mousePoint.y - height/2;
// Don't scroll outside desktop area.
if (sourceRect.left < 0)
{
sourceRect.left = 0;
}
if (sourceRect.left > NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN) - width)
{
sourceRect.left = NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN) - width;
}
sourceRect.right = sourceRect.left + width;
if (sourceRect.top < 0)
{
sourceRect.top = 0;
}
if (sourceRect.top > NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN) - height)
{
sourceRect.top = NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN) - height;
}
sourceRect.bottom = sourceRect.top + height;
if (this.window == null)
{
timer.IsEnabled = false;
return;
}
//if (this.window.IsDisposed)
//{
// timer.IsEnabled = false;
// return;
//}
// Set the source rectangle for the magnifier control.
NativeMethods.MagSetWindowSource(hwndMag, sourceRect);
// Reclaim topmost status, to prevent unmagnified menus from remaining in view.
NativeMethods.SetWindowPos(hwnd, NativeMethods.HWND_TOPMOST, 0, 0, 0, 0,
(int)SetWindowPosFlags.SWP_NOACTIVATE | (int)SetWindowPosFlags.SWP_NOMOVE | (int)SetWindowPosFlags.SWP_NOSIZE);
// Force redraw.
NativeMethods.InvalidateRect(hwndMag, IntPtr.Zero, true);
}
public float Magnification
{
get { return magnification; }
set
{
if (magnification != value)
{
magnification = value;
// Set the magnification factor.
Transformation matrix = new Transformation(magnification);
NativeMethods.MagSetWindowTransform(hwndMag, ref matrix);
}
}
}
protected void SetupMagnifier()
{
if (!initialized)
return;
IntPtr hInst;
hInst = NativeMethods.GetModuleHandle(null);
// Make the window opaque.
//form.AllowTransparency = true; (done in xaml)
//window.Background = Brushes.Transparent; (done in xaml)
//window.Opacity = 255;
// Create a magnifier control that fills the client area.
NativeMethods.GetClientRect(hwnd, ref magWindowRect);
hwndMag = NativeMethods.CreateWindow((int)ExtendedWindowStyles.WS_EX_CLIENTEDGE, NativeMethods.WC_MAGNIFIER,
"MagnifierWindow", (int)WindowStyles.WS_CHILD | (int)MagnifierStyle.MS_SHOWMAGNIFIEDCURSOR |
(int)WindowStyles.WS_VISIBLE,
magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, hwnd, IntPtr.Zero, hInst, IntPtr.Zero);
if (hwndMag == IntPtr.Zero)
{
return;
}
// Set the magnification factor.
Transformation matrix = new Transformation(magnification);
NativeMethods.MagSetWindowTransform(hwndMag, ref matrix);
}
protected void RemoveMagnifier()
{
if (initialized)
NativeMethods.MagUninitialize();
}
protected virtual void Dispose(bool disposing)
{
timer.IsEnabled = false;
//if (disposing)
// timer.Dispose();
timer = null;
window.SizeChanged -= form_Resize;
RemoveMagnifier();
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
XAML :
<Window x:Class="WpfApplication11.MagnifierWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MagnifierWindow" Height="350" Width="525" AllowsTransparency="True" WindowStyle="None">
<Window.Background>
<SolidColorBrush />
</Window.Background>
는 클래스 I을 사용하여 위해 -
public class Magnifier : IDisposable
{
private Form form;
private IntPtr hwndMag;
private float magnification;
private bool initialized;
private RECT magWindowRect = new RECT();
private System.Windows.Forms.Timer timer;
public Magnifier(Form form)
{
if (form == null)
throw new ArgumentNullException("form");
magnification = 2.0f;
this.form = form;
this.form.Resize += new EventHandler(form_Resize);
this.form.FormClosing += new FormClosingEventHandler(form_FormClosing);
timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
initialized = NativeMethods.MagInitialize();
if (initialized)
{
SetupMagnifier();
timer.Interval = NativeMethods.USER_TIMER_MINIMUM;
timer.Enabled = true;
}
}
void form_FormClosing(object sender, FormClosingEventArgs e)
{
timer.Enabled = false;
}
void timer_Tick(object sender, EventArgs e)
{
UpdateMaginifier();
}
void form_Resize(object sender, EventArgs e)
{
ResizeMagnifier();
}
~Magnifier()
{
Dispose(false);
}
protected virtual void ResizeMagnifier()
{
if (initialized && (hwndMag != IntPtr.Zero))
{
NativeMethods.GetClientRect(form.Handle, ref magWindowRect);
// Resize the control to fill the window.
NativeMethods.SetWindowPos(hwndMag, IntPtr.Zero,
magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, 0);
}
}
public virtual void UpdateMaginifier()
{
if ((!initialized) || (hwndMag == IntPtr.Zero))
return;
POINT mousePoint = new POINT();
RECT sourceRect = new RECT();
NativeMethods.GetCursorPos(ref mousePoint);
int width = (int)((magWindowRect.right - magWindowRect.left)/magnification);
int height = (int)((magWindowRect.bottom - magWindowRect.top)/magnification);
sourceRect.left = mousePoint.x - width/2;
sourceRect.top = mousePoint.y - height/2;
// Don't scroll outside desktop area.
if (sourceRect.left < 0)
{
sourceRect.left = 0;
}
if (sourceRect.left > NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN) - width)
{
sourceRect.left = NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN) - width;
}
sourceRect.right = sourceRect.left + width;
if (sourceRect.top < 0)
{
sourceRect.top = 0;
}
if (sourceRect.top > NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN) - height)
{
sourceRect.top = NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN) - height;
}
sourceRect.bottom = sourceRect.top + height;
if (this.form == null)
{
timer.Enabled = false;
return;
}
if (this.form.IsDisposed)
{
timer.Enabled = false;
return;
}
// Set the source rectangle for the magnifier control.
NativeMethods.MagSetWindowSource(hwndMag, sourceRect);
// Reclaim topmost status, to prevent unmagnified menus from remaining in view.
NativeMethods.SetWindowPos(form.Handle, NativeMethods.HWND_TOPMOST, 0, 0, 0, 0,
(int)SetWindowPosFlags.SWP_NOACTIVATE | (int)SetWindowPosFlags.SWP_NOMOVE | (int)SetWindowPosFlags.SWP_NOSIZE);
// Force redraw.
NativeMethods.InvalidateRect(hwndMag, IntPtr.Zero, true);
}
public float Magnification
{
get { return magnification; }
set
{
if (magnification != value)
{
magnification = value;
// Set the magnification factor.
Transformation matrix = new Transformation(magnification);
NativeMethods.MagSetWindowTransform(hwndMag, ref matrix);
}
}
}
protected void SetupMagnifier()
{
if (!initialized)
return;
IntPtr hInst;
hInst = NativeMethods.GetModuleHandle(null);
// Make the window opaque.
form.AllowTransparency = true;
form.TransparencyKey = Color.Empty;
form.Opacity = 255;
// Create a magnifier control that fills the client area.
NativeMethods.GetClientRect(form.Handle, ref magWindowRect);
hwndMag = NativeMethods.CreateWindow((int)ExtendedWindowStyles.WS_EX_CLIENTEDGE, NativeMethods.WC_MAGNIFIER,
"MagnifierWindow", (int)WindowStyles.WS_CHILD | (int)MagnifierStyle.MS_SHOWMAGNIFIEDCURSOR |
(int)WindowStyles.WS_VISIBLE,
magWindowRect.left, magWindowRect.top, magWindowRect.right, magWindowRect.bottom, form.Handle, IntPtr.Zero, hInst, IntPtr.Zero);
if (hwndMag == IntPtr.Zero)
{
return;
}
// Set the magnification factor.
Transformation matrix = new Transformation(magnification);
NativeMethods.MagSetWindowTransform(hwndMag, ref matrix);
}
protected void RemoveMagnifier()
{
if (initialized)
NativeMethods.MagUninitialize();
}
protected virtual void Dispose(bool disposing)
{
timer.Enabled = false;
if (disposing)
timer.Dispose();
timer = null;
form.Resize -= form_Resize;
RemoveMagnifier();
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
WPF 코드에서 나는 단지 Magnifer 클래스를 수정 Fo에서 초기화하십시오. rm/Window의 생성자. ,
- 추가 "HWND"필드를 돋보기 생성자에서 초기화 :
-Changes 나는 WPF에서했다.
- 대체 됨 System.Windows.Forms.Timer가 으로 대체되었습니다. System.Windows.Threading.DispatcherTimer.
- 변경된 양식. window.SizeChanged 및 form.FormClosing을 window.Closing으로 변경했습니다. 하지만 이건 맞지 않아?
- 부터 UpdateMagnifier()에 (this.window.IsDisposed)가있는 경우 Window에 IsDisposed 속성이 없습니다.
- Dispose()의 처분 확인에 대한 설명입니다.
-I 문자 제한으로 인해 네이티브 메서드 및 구조를 추가 할 수 없습니다.
도움을 주시면 대단히 감사하겠습니다.
나를 위해 여기에서 작동하지 않았습니다 ... 알아 냈습니까? – JobaDiniz
winforms 코드는 버그가 있습니다 ... 작동하기 시작할 때까지 창의 크기를 조정해야합니다. 그렇지 않으면 검정색 화면이 표시됩니다. – JobaDiniz