Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement DwmExtendFrameIntoClientArea #1430

Open
ghost opened this issue Apr 24, 2022 · 7 comments
Open

Implement DwmExtendFrameIntoClientArea #1430

ghost opened this issue Apr 24, 2022 · 7 comments

Comments

@ghost
Copy link

ghost commented Apr 24, 2022

STOP! Read this before creating an issue.

This is not a Question and Answer forum. For general questions and support, use
the JNA users' group. Please search
message history there and on existing issues for duplicates. You may also find answers on
the Using the Library section of the project
home page or in the FAQ.

Do NOT file an issue if you:

  • Are receiving a segfault or getting an Exception from your own JNA function/structure mapping
  • Want to know how to map a function
  • Want to know future plans for JNA
  • Want technical help or support of any kind
  • Are not yet sure if the issue you are facing is actually a JNA bug

All of these questions belong on the mailing list.

If you are certain you are reporting a bug, or you have a feature request that is
not of the form "please map this API function", then you may open an issue.

Provide complete information about the problem

  1. Version of JNA and related jars: jna-plat = 5.11.0 & jna = 5.11.0
  2. Version and vendor of the java virtual machine: Java(TM) SE Runtime Environment (build 17.0.2+8-LTS-86)
    Java HotSpot(TM) 64-Bit Server VM (build 17.0.2+8-LTS-86, mixed mode, sharing)
  3. Operating system Windows 10 212h
  4. System architecture (CPU type, bitness of the JVM) 64 and 64
  5. Complete description of the problem: User32.INSTANCE.DwmExtendFrameIntoClientArea doesnt exist
  6. Steps to reproduce: User32.INSTANCE.DwmExtendFrameIntoClientArea
@dbwiddis
Copy link
Contributor

dbwiddis commented Apr 24, 2022

From the FAQ

JNA is missing function XXX in its platform library mappings

No, it's not, it's just waiting for you to add it :)

public interface MyUser32 extends User32 {
    // DEFAULT_OPTIONS is critical for W32 API functions to simplify ASCII/UNICODE details
    MyUser32 INSTANCE = (MyUser32)Native.load("user32", W32APIOptions.DEFAULT_OPTIONS);
    void ThatFunctionYouReallyNeed();
}

In your case, put HRESULT DwmExtendFrameIntoClientArea(HWND hWnd, MARGINS pMarInset) in place of void ThatFunctionYouReallyNeed(), and map the MARGINS structure:

@FieldOrder({ "cxLeftWidth", "cxRidghtWidth", "cyTopHeight", "cyBottomHeight" })
class MARGINS extends Structure {
  public int cxLeftWidth;
  public int cxRightWidth;
  public int cyTopHeight;
  public int cyBottomHeight;
}

JNA is a user-supported library. Functionality like the above is only added when users who need it contribute. Please submit a PR with these changes and we'll include it in the next version.

@ghost
Copy link
Author

ghost commented Apr 24, 2022

Wow thankyou!

@ghost
Copy link
Author

ghost commented Apr 24, 2022

image
github undefined buttons

@ghost
Copy link
Author

ghost commented Apr 24, 2022

I did end up getting an error while calling and read through the FAQ

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'DwmExtendFrameIntoClientArea': The specified procedure could not be found.

	at com.sun.jna.Function.<init>(Function.java:252)
	at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:600)
	at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:576)
	at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:562)
	at com.sun.jna.Library$Handler.invoke(Library.java:243)
	at net.skylix.elixor.elixorFX.$Proxy2.DwmExtendFrameIntoClientArea(Unknown Source)
	at net.skylix.elixor.elixorFX.ElixorFX.init(ElixorFX.java:65)
	at com.github.skylixgh.hello.MyApp.main(MyApp.java:104)

But I didn't find much.

package net.skylix.elixor.elixorFX;

import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.win32.W32APIOptions;
import net.skylix.elixor.elixorFX.jna.MARGINS;

import javax.swing.*;

import static com.sun.jna.platform.win32.WinUser.*;

interface EUser32 extends User32 {
    EUser32 INSTANCE = Native.load("user32", EUser32.class, W32APIOptions.DEFAULT_OPTIONS);
    HRESULT DwmExtendFrameIntoClientArea(HWND hwnd, MARGINS pMarInset);
}

public class ElixorFX {
    /**
     * Extended client area example
     */
    public static void init() {
        ModJFrame frame = new ModJFrame();
        frame.setVisible(true);

        HWND hwin = frame.getHWND();

//        if (message == WM_ACTIVATE)
//        {
//            // Extend the frame into the client area.
//            MARGINS margins;
//
//            margins.cxLeftWidth = LEFTEXTENDWIDTH;      // 8
//            margins.cxRightWidth = RIGHTEXTENDWIDTH;    // 8
//            margins.cyBottomHeight = BOTTOMEXTENDWIDTH; // 20
//            margins.cyTopHeight = TOPEXTENDWIDTH;       // 27
//
//            hr = DwmExtendFrameIntoClientArea(hWnd, &margins);
//
//            if (!SUCCEEDED(hr))
//            {
//                // Handle the error.
//            }
//
//            fCallDWP = true;
//            lRet = 0;
//        }
        // we will implement the code above

        // Listen for messages
        MSG msg = new MSG();
        int WM_ACTIVATE = 0x0006;

        System.out.println("WM_ACTIVATE");

        // Extend the frame into the client area.
        MARGINS margins = new MARGINS() {{
            cxLeftWidth = 8;
            cxRightWidth = 8;
            cyBottomHeight = 20;
            cyTopHeight = 27;
        }};

        WinNT.HRESULT hr = EUser32.INSTANCE.DwmExtendFrameIntoClientArea(hwin, margins);

        while (User32.INSTANCE.GetMessage(msg, hwin, 0, 0) != 0) {
            User32.INSTANCE.TranslateMessage(msg);
            User32.INSTANCE.DispatchMessage(msg);

            if (msg.message == WM_QUIT) {
                break;
            } else if (msg.message == WM_ACTIVATE) {}
        }
    }

    public static class ModJFrame extends JFrame {
        public ModJFrame() {
            super();
        }

        public HWND getHWND() {
            HWND hwnd = new HWND();
            hwnd.setPointer(Native.getComponentPointer(this));

            return hwnd;
        }
    }
}

I think I did everything right

@dbwiddis
Copy link
Contributor

The User32 in the FAQ template is just an example. The Windows API tells you it's in Dwmapi.dll. This library is not yet mapped in JNA so you'd extend Library rather than a JNA superclass.

@ghost
Copy link
Author

ghost commented Apr 24, 2022

sorry, im a newbie with native stuff, any docs here that could guide me on how to implement new methods for Library and how to point it to the DLL

@dbwiddis
Copy link
Contributor

dbwiddis commented Apr 24, 2022

This extended discussion really belongs on the mailing list. But just change your EUser32 interface to a Dwmapi interface (extending StdCallLibrary), and load the "dwmapi" native library. There are numerous examples to look at here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants