C #: Win32 Hooks (1) Enable the next pop-up sub-form to automatically display in the center of the parent form

Source: Internet
Author: User

/*----------------------------------------------------------
File Name: FormHelper. cs

Using System;
Using System. Runtime. InteropServices;
Using System. Windows. Forms;
 
Namespace Splash. Windows. Forms
{
/// <Summary>
/// Form extension:
/// 1. The child form is automatically displayed in the center of the parent form
/// </Summary>
Public static class FormHelper
{
/// <Summary>
/// The child form is automatically displayed in the center of the parent form
/// </Summary>
/// <Param name = "owner"> form to center the subform </param>
/// <Remarks> Extension Method </remarks>
Public static void CenterChild (this IWin32Window owner)
{
CenterChildHelper helper = new CenterChildHelper ();
Helper. Run (owner );
}
 
/// <Summary>
/// Automatically display sub-forms in the center of the parent form based on Hook
/// </Summary>
Private class CenterChildHelper
{
Private const Int32 WH_CBT = 5;
Private const Int32 HCBT_ACTIVATE = 5;
Private const Int32 GWL_HINSTANCE =-6;
 
Private IntPtr _ hhk; // hook handle
Private IntPtr _ parent; // parent form handle
Private GCHandle _ gch;
 
Public void Run (IWin32Window owner)
{
NativeMethods. CBTProc CenterChildHookProc = new NativeMethods. CBTProc (CenterChildCallBack );
 
// Allocate a new GCHandle to prevent objects from being recycled.
_ Gch = GCHandle. Alloc (CenterChildHookProc );
 
_ Parent = owner. Handle; // parent form Handle
 
// Note: dwThreadId is System. Threading. Thread. CurrentThread. ManagedThreadId does not work
_ Hhk = NativeMethods. SetWindowsHookEx (WH_CBT, CenterChildHookProc, IntPtr. Zero, NativeMethods. GetCurrentThreadId ());
}
 
Private IntPtr CenterChildCallBack (Int32 nCode, IntPtr wParam, IntPtr lParam)
{
If (nCode = HCBT_ACTIVATE)
{// Parent form
NativeMethods. RECT formRect;
NativeMethods. GetWindowRect (_ parent, out formRect );
 
// Subform
NativeMethods. RECT messageBoxRect;
NativeMethods. GetWindowRect (wParam, out messageBoxRect );
 
Int32 width = messageBoxRect. right-messageBoxRect. left; // message form width
Int32 height = messageBoxRect. bottom-messageBoxRect. top; // message form height
Int32 xPos = (formRect. left + formRect. right-width)> 1; // The X coordinate in the upper left corner of the message form in the center of the parent form
Int32 yPos = (formRect. top + formRect. bottom-height)> 1; // Y coordinate of the message form in the upper left corner of the center of the parent form
 
// Move the message form to the center of the parent form
NativeMethods. MoveWindow (wParam, xPos, yPos, width, height, false );
 
// Uninstall the hook
NativeMethods. UnhookWindowsHookEx (_ hhk );
 
// Release the allocated GCHandle
_ Gch. Free ();
}
 
// Allow operations
Return IntPtr. Zero;
}
}
 
Private static class NativeMethods
{
[StructLayout (LayoutKind. Sequential)]
Internal struct RECT
{
Public Int32 left;
Public Int32 top;
Public Int32 right;
Public Int32 bottom;
}
 
/// <Summary>
/// CBTProc delegation statement
/// </Summary>
/// <Param name = "nCode"> HCBT_ACTIVATE: the system will activate a window. </param>
/// <Param name = "wParam"> the window handle to be activated </param>
/// <Param name = "lParam"> point to the CBTACTIVATESTRUCT structure </param>
/// <Returns>
/// 0: execute this operation
/// 1: block this operation
/// </Returns>
Internal delegate IntPtr CBTProc (Int32 nCode, IntPtr wParam, IntPtr lParam );
 
[DllImport ("user32.dll", SetLastError = true)]
Internal static extern IntPtr SetWindowsHookEx (Int32 idHook, CBTProc lpfn, IntPtr hMod, Int32 dwThreadId );
 
[DllImport ("user32.dll")]
[Return: financialas (UnmanagedType. Bool)]
Internal static extern Boolean UnhookWindowsHookEx (IntPtr hhk );
 
[DllImport ("user32.dll")]
[Return: financialas (UnmanagedType. Bool)]
Internal static extern Boolean GetWindowRect (IntPtr hWnd, out RECT lpRect );
 
[DllImport ("user32.dll")]
[Return: financialas (UnmanagedType. Bool)]
Internal static extern Boolean MoveWindow (IntPtr hWnd, Int32 X, Int32 Y, Int32 nWidth, Int32 nHeight, [financialas (UnmanagedType. Bool)] Boolean bRepaint );
 
[DllImport ("kernel32.dll")]
Internal static extern Int32 GetCurrentThreadId ();
}
}
}

 

From Qin Jianhui's column

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.