Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

Commit

Permalink
Merge pull request #384 from vatsanm/master2
Browse files Browse the repository at this point in the history
Adding User32.SetWindowLongPtr
  • Loading branch information
AArnott authored May 2, 2018
2 parents 2eaa7f2 + bb32926 commit 9ecf26c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/User32/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ PInvoke.User32.SendMessageTimeoutFlags.SMTO_NOTIMEOUTIFNOTHUNG = 8 -> PInvoke.Us
PInvoke.User32.WindowMessage.WM_DPICHANGED_AFTERPARENT = 739 -> PInvoke.User32.WindowMessage
PInvoke.User32.WindowMessage.WM_DPICHANGED_BEFOREPARENT = 738 -> PInvoke.User32.WindowMessage
PInvoke.User32.WindowMessage.WM_GETDPISCALEDSIZE = 740 -> PInvoke.User32.WindowMessage
PInvoke.User32.WindowLongIndexFlags.GWLP_ID = PInvoke.User32.WindowLongIndexFlags.GWL_STYLE | PInvoke.User32.WindowLongIndexFlags.DWLP_DLGPROC -> PInvoke.User32.WindowLongIndexFlags
PInvoke.User32.WindowLongIndexFlags.GWLP_USERDATA = -21 -> PInvoke.User32.WindowLongIndexFlags
PInvoke.User32.WindowLongIndexFlags.GWLP_WNDPROC = PInvoke.User32.WindowLongIndexFlags.GWL_STYLE | PInvoke.User32.WindowLongIndexFlags.DWLP_DLGPROC | PInvoke.User32.WindowLongIndexFlags.DWLP_USER -> PInvoke.User32.WindowLongIndexFlags
PInvoke.User32.mouse_eventFlags
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_ABSOLUTE = 32768 -> PInvoke.User32.mouse_eventFlags
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_HWHEEL = 4096 -> PInvoke.User32.mouse_eventFlags
Expand All @@ -53,6 +56,7 @@ static PInvoke.User32.AdjustWindowRectExForDpi(System.IntPtr lpRect, PInvoke.Use
static PInvoke.User32.CreateWindowEx(PInvoke.User32.WindowStylesEx dwExStyle, short lpClassName, string lpWindowName, PInvoke.User32.WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, System.IntPtr hWndParent, System.IntPtr hMenu, System.IntPtr hInstance, System.IntPtr lpParam) -> System.IntPtr
static PInvoke.User32.CreateWindowEx(PInvoke.User32.WindowStylesEx dwExStyle, short lpClassName, string lpWindowName, PInvoke.User32.WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, System.IntPtr hWndParent, System.IntPtr hMenu, System.IntPtr hInstance, void* lpParam) -> System.IntPtr
static PInvoke.User32.GetNextWindow(System.IntPtr hWnd, PInvoke.User32.GetNextWindowCommands wCmd) -> System.IntPtr
static PInvoke.User32.SetWindowLongPtr(System.IntPtr hWnd, PInvoke.User32.WindowLongIndexFlags nIndex, System.IntPtr dwNewLong) -> System.IntPtr
static PInvoke.User32.SystemParametersInfoForDpi(PInvoke.User32.SystemParametersInfoAction uiAction, int uiParam, System.IntPtr pvParam, PInvoke.User32.SystemParametersInfoFlags fWinIni, int dpi) -> bool
static PInvoke.User32.mouse_event(PInvoke.User32.mouse_eventFlags dwFlags, int dx, int dy, int dwData, System.IntPtr dwExtraInfo) -> void
static extern PInvoke.User32.AdjustWindowRectExForDpi(PInvoke.RECT* lpRect, PInvoke.User32.WindowStyles dwStyle, bool bMenu, PInvoke.User32.WindowStylesEx dwExStyle, int dpi) -> bool
Expand All @@ -78,6 +82,7 @@ static extern PInvoke.User32.SendMessageTimeout(System.IntPtr hWnd, PInvoke.User
static extern PInvoke.User32.SetDialogControlDpiChangeBehavior(System.IntPtr hwnd, PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS mask, PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS values) -> bool
static extern PInvoke.User32.SetDialogDpiChangeBehavior(System.IntPtr hDlg, PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS mask, PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS values) -> bool
static extern PInvoke.User32.SetLastErrorEx(uint dwErrCode, uint dwType) -> void
static extern PInvoke.User32.SetWindowLongPtr(System.IntPtr hWnd, PInvoke.User32.WindowLongIndexFlags nIndex, void* dwNewLong) -> void*
static extern PInvoke.User32.SetProcessDpiAwarenessContext(System.IntPtr dpiAWarenessContext) -> bool
static extern PInvoke.User32.SetThreadDpiAwarenessContext(System.IntPtr dpiContext) -> System.IntPtr
static extern PInvoke.User32.SetThreadDpiHostingBehavior(PInvoke.User32.DPI_HOSTING_BEHAVIOR dpiHostingBehavior) -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
Expand Down
3 changes: 3 additions & 0 deletions src/User32/User32+WindowLongIndexFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ public enum WindowLongIndexFlags : int
GWLP_HINSTANCE = -6,
GWLP_HWNDPARENT = -8,
GWL_ID = -12,
GWLP_ID = GWL_ID,
GWL_STYLE = -16,
GWL_USERDATA = -21,
GWLP_USERDATA = GWL_USERDATA,
GWL_WNDPROC = -4,
GWLP_WNDPROC = GWL_WNDPROC,
DWLP_USER = 0x8,
DWLP_MSGRESULT = 0x0,
DWLP_DLGPROC = 0x4
Expand Down
80 changes: 79 additions & 1 deletion src/User32/User32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,87 @@ public delegate void WinEventProc(
[DllImport(nameof(User32), SetLastError = true)]
public static extern int MessageBoxIndirect(ref MSGBOXPARAMS lpMsgBoxParams);

[DllImport(nameof(User32), CharSet = CharSet.Unicode)]
[DllImport(nameof(User32), SetLastError = true)]
public static extern int SetWindowLong(IntPtr hWnd, WindowLongIndexFlags nIndex, SetWindowLongFlags dwNewLong);

/// <summary>
/// Changes an attribute of the specified window. The function also sets a value at the specified
/// offset in the extra window memory.
/// </summary>
/// <param name="hWnd">A handle to the window and, indirectly, the class to which the window belongs.
/// The SetWindowLongPtr function fails if the process that owns the window specified by the
/// <paramref name="hWnd"/> parameter is at a higher process privilege in the UIPI hierarchy than the
/// process the calling thread resides in.</param>
/// <param name="nIndex">The zero-based offset to the value to be set. Valid values are in the range zero
/// through the number of bytes of extra window memory, minus the size of a LONG_PTR. To set any other value,
/// specify one of the following values.
/// +---------------------+---------------------------------------------------------------------------------------------------+
/// | Value | Meaning |
/// +---------------------+---------------------------------------------------------------------------------------------------+
/// | GWL_EXSTYLE(-20) | Sets a new extended window style. |
/// | GWLP_HINSTANCE(-6) | Sets a new application instance handle. |
/// | GWLP_ID(-12) | Sets a new identifier of the child window.The window cannot be a top-level window. |
/// | GWL_STYLE (-16) | Sets a new window style. |
/// | GWLP_USERDATA (-21) | Sets the user data associated with the window.This data is intended for use by the application |
/// | | that created the window. Its value is initially zero. |
/// | GWLP_WNDPROC (-4) | Sets a new address for the window procedure. |
/// +---------------------+---------------------------------------------------------------------------------------------------+
///
/// The following values are also available when the hWnd parameter identifies a dialog box.
///
/// +-------------------------------------------------+---------------------------------------------------------------------------+
/// | Value | Meaning |
/// +-------------------------------------------------+---------------------------------------------------------------------------+
/// | DWLP_DLGPROC (DWLP_MSGRESULT + sizeof(LRESULT)) | Sets the new pointer to the dialog box procedure. |
/// | DWLP_MSGRESULT (0) | Sets the return value of a message processed in the dialog box procedure. |
/// | DWLP_USER (DWLP_DLGPROC + sizeof(DLGPROC)) | Sets new extra info |
/// +-------------------------------------------------+---------------------------------------------------------------------------+
/// </param>
/// <param name="dwNewLong">The replacement value.</param>
/// <returns>
/// <para>If the function succeeds, the return value is the previous value of the specified offset.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// <para>If the previous value is zero and the function succeeds, the return value is zero, but the function does
/// not clear the last error information. To determine success or failure, clear the last error information by
/// calling SetLastError with 0, then call SetWindowLongPtr. Function failure will be indicated by a return value of
/// zero and a GetLastError result that is nonzero.</para>
/// </returns>
/// <remarks>
/// <list type="bullet">
/// <item>The return type, and the type of <paramref name="dwNewLong"/> are both LONG_PTR.
/// LONG_PTR is defined as <code>__int64</code> on 64-bit platforms, and it is defined as <code>long</code>
/// on 32-bit platforms. This definition fits nicely with now <see cref="IntPtr"/> works on 32-bit vs. 64-bit
/// platforms.</item>
/// <item>Windows XP/2000: The SetWindowLongPtr function fails if the window specified by the
/// <paramref name="hWnd"/> parameter does not belong to the same process as the calling thread.</item>
/// <item>
/// <para>Certain window data is cached, so changes you make using SetWindowLongPtr will not take effect until you call
/// the SetWindowPos function.</para>
/// <para>If you use SetWindowLongPtr with the <see cref="WindowLongIndexFlags.GWLP_WNDPROC"/> index to replace the window procedure,
/// the window procedure must conform to the guidelines specified in the description of the WindowProc callback function.</para>
/// <para>If you use SetWindowLongPtr with the <see cref="WindowLongIndexFlags.DWLP_MSGRESULT"/> index to set the return value for a
/// message processed by a dialog box procedure, the dialog box procedure should return TRUE directly afterward. Otherwise, if you call
/// any function that results in your dialog box procedure receiving a window message, the nested window message could overwrite the return value
/// you set by using <see cref="WindowLongIndexFlags.DWLP_MSGRESULT"/>.</para>
/// <para>Calling SetWindowLongPtr with the <see cref="WindowLongIndexFlags.GWLP_WNDPROC"/> index creates a subclass of the window
/// class used to create the window. An application can subclass a system class, but should not subclass a window class created by another process.
/// The SetWindowLongPtr function creates the window subclass by changing the window procedure associated with a particular
/// window class, causing the system to call the new window procedure instead of the previous one. An application must pass
/// any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc.
/// This allows the application to create a chain of window procedures.</para>
/// <para>Reserve extra window memory by specifying a nonzero value in the <see cref="WNDCLASSEX.cbWndExtra"/> member of the
/// <see cref="WNDCLASSEX"/> structure used with the RegisterClassEx function.</para>
/// <para>Do not call SetWindowLongPtr with the <see cref="WindowLongIndexFlags.GWLP_HWNDPARENT"/> index to change the parent of a
/// child window. Instead, use the SetParent function.</para>
/// <para>If the window has a class style of <see cref="ClassStyles.CS_CLASSDC"/> or <see cref="ClassStyles.CS_PARENTDC"/>, do not set
/// the extended window styles <see cref="WindowStylesEx.WS_EX_COMPOSITED"/> or <see cref="WindowStylesEx.WS_EX_LAYERED"/>.</para>
/// <para>Calling SetWindowLongPtr to set the style on a progressbar will reset its position.</para>
/// </item>
/// </list>
/// </remarks>
[DllImport(nameof(User32), SetLastError = true)]
public static extern unsafe void* SetWindowLongPtr(IntPtr hWnd, WindowLongIndexFlags nIndex, void* dwNewLong);

[DllImport(nameof(User32), SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int GetWindowLong(IntPtr hWnd, WindowLongIndexFlags nIndex);

Expand Down

0 comments on commit 9ecf26c

Please sign in to comment.