더 큰 프로젝트에 응용 프로그램 스위처를 추가하려고합니다. 그것은 Windows XP/Vista/7/8에서 작동해야합니다. Java 1.7을 사용하고 있습니다. 다음은 내가 겪고있는 문제 중 일부를 보여주기 위해 작성한 샘플 애플리케이션입니다. 나는 JNA에게 아주 새로운 사람입니다.Java - JNA를 사용하는 Windows 작업 표시 줄 - 어떻게 창 아이콘 (HICON)을 Java 이미지로 변환합니까?
테스트 응용 프로그램의 기초가되는 this answer (및 기타 다수!)의 'Hovercraft Full of Eels'에 감사드립니다. 여기
내 질문은 다음과 같습니다이미지 그리기 - 나는 창 아이콘에서 얻을 이미지는 흑백으로 그려지고있다. 나는 맥도웰에 의해 this answer에서 getImageForWindow의 코드를 수정했다. (고마워!). HICON 객체를 java.awt.Image로 변환하는 더 좋은 방법이 있습니까? com.sun.jna.platform.win32.W32API.HICON에서 'fromNative'라는 메서드가 있음을 알았지 만 사용 방법을 알 수 없습니다. 아이콘 얻기
- 나는 아이콘 핸들을 얻기 위해 사용하는 호출을 GetClassLongW (HWND, GCL_HICON)는, 64 비트 윈도우에서 아이콘을 반환하지 않습니다. 그걸 위해 GetClassLongPtr이 필요하다고 생각하지만 JNA를 통해 액세스 할 수없는 것 같습니다. 내가 this C++ answer에서 이루어집니다 무엇을 복제하려하지만 난 2 (GetAncestor 등) 및 3을 얻기 위해 (STATE_SYSTEM_INVISIBLE)를 관리 할 수 -
에서 Alt-탭 팝업에 따라, 올바른 창 목록 얻기 Java에서 구현 된 검사. 나는 제목이 공백 인 창을 제외시키는 가난한 대체품을 사용하고 있습니다. (일부 합법적 인 창을 무시합니다).
참고 : JNA와 플랫폼 항아리는이 예제를 실행하는 데 필요한 : 나는 해결 방법 내 목적을 위해 할 것입니다 것으로 나타났습니다
package test;
import static test.WindowSwitcher.User32DLL.*;
import static test.WindowSwitcher.Gdi32DLL.*;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class WindowSwitcher
{
public static void main(String args[])
{
JFrame JF = new JFrame();
JPanel JP = new JPanel(new GridLayout(0, 1));
JF.getContentPane().add(JP);
Vector<WindowInfo> V = getActiveWindows();
for (int i = 0; i < V.size(); i++)
{
final WindowInfo WI = V.elementAt(i);
JButton JB = new JButton(WI.title);
if(WI.image != null)
{
JB.setIcon(new ImageIcon(WI.image));
}
JB.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
SetForegroundWindow(WI.hWnd);
}
});
JP.add(JB);
}
JF.setSize(600,50+V.size()*64);
JF.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JF.setAlwaysOnTop(true);
JF.setFocusableWindowState(false);
JF.setVisible(true);
}
public static Vector<WindowInfo> getActiveWindows()
{
final Vector<WindowInfo> V = new Vector();
EnumWindows(new WNDENUMPROC()
{
public boolean callback(Pointer hWndPointer, Pointer userData)
{
HWND hWnd = new HWND(hWndPointer);
// Make sure the window is visible
if(IsWindowVisible(hWndPointer))
{
int GWL_EXSTYLE = -20;
long WS_EX_TOOLWINDOW = 0x00000080L;
// Make sure this is not a tool window
if((GetWindowLongW(hWndPointer, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) == 0)
{
// Get the title bar text for the window
char[] windowText = new char[512];
GetWindowTextW(hWnd, windowText, windowText.length);
String wText = Native.toString(windowText);
// Make sure the text is not null or blank
if(!(wText == null || wText.trim().equals("")))
{
// Get the icon image for the window (if available)
Image image = getImageForWindow(hWnd, wText);
// This window is a valid taskbar button, add a WindowInfo object to the return vector
V.add(new WindowInfo(wText, hWnd, image));
}
}
}
return true;
}
}, null);
return V;
}
public static Image getImageForWindow(HWND hWnd, String wText)
{
// Get an image from the icon for this window
int hicon = GetClassLongW(hWnd, GCL_HICON);
if(hicon == 0)
return null;
Pointer hIcon = new Pointer(hicon);
int width = 64;
int height = 64;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
draw(image, hIcon, DI_NORMAL);
BufferedImage mask = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
draw(mask, hIcon, DI_MASK);
applyMask(image, mask);
return image;
}
public static void draw(BufferedImage image, Pointer hIcon, int diFlags)
{
int width = image.getWidth();
int height = image.getHeight();
Pointer hdc = CreateCompatibleDC(Pointer.NULL);
Pointer bitmap = CreateCompatibleBitmap(hdc, width, height);
SelectObject(hdc, bitmap);
DrawIconEx(hdc, 0, 0, hIcon, width, height, 0, Pointer.NULL, diFlags);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < width; y++)
{
int rgb = GetPixel(hdc, x, y);
image.setRGB(x, y, rgb);
}
}
DeleteObject(bitmap);
DeleteDC(hdc);
}
private static void applyMask(BufferedImage image,
BufferedImage mask)
{
int width = image.getWidth();
int height = image.getHeight();
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
int masked = mask.getRGB(x, y);
if ((masked & 0x00FFFFFF) == 0)
{
int rgb = image.getRGB(x, y);
rgb = 0xFF000000 | rgb;
image.setRGB(x, y, rgb);
}
}
}
}
static class User32DLL
{
static
{
Native.register("user32");
}
public static native int GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount);
public static native boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);
public static interface WNDENUMPROC extends com.sun.jna.win32.StdCallLibrary.StdCallCallback
{
boolean callback(Pointer hWnd, Pointer arg);
}
public static native boolean IsWindowVisible(Pointer hWnd);
public static native boolean SetForegroundWindow(HWND hWnd);
public static native int GetWindowLongW(Pointer hWnd, int nIndex);
public static int GCL_HICON = -14;
public static int GCL_HICONSM = -34;
public static native int GetClassLongW(HWND hWnd, int nIndex);
/** @see #DrawIconEx(Pointer, int, int, Pointer, int, int, int, Pointer, int) */
public static final int DI_COMPAT = 4;
public static final int DI_DEFAULTSIZE = 8;
public static final int DI_IMAGE = 2;
public static final int DI_MASK = 1;
public static final int DI_NORMAL = 3;
public static final int DI_APPBANDING = 1;
/** http://msdn.microsoft.com/en-us/library/ms648065(VS.85).aspx */
public static native boolean DrawIconEx(Pointer hdc, int xLeft,
int yTop, Pointer hIcon, int cxWidth, int cyWidth,
int istepIfAniCur, Pointer hbrFlickerFreeDraw,
int diFlags);
}
static class Gdi32DLL
{
static
{
Native.register("gdi32");
}
/** http://msdn.microsoft.com/en-us/library/dd183489(VS.85).aspx */
public static native Pointer CreateCompatibleDC(Pointer hdc);
/** http://msdn.microsoft.com/en-us/library/dd183488(VS.85).aspx */
public static native Pointer CreateCompatibleBitmap(Pointer hdc, int nWidth, int nHeight);
/** http://msdn.microsoft.com/en-us/library/dd162957(VS.85).aspx */
public static native Pointer SelectObject(Pointer hdc, Pointer hgdiobj);
/** http://msdn.microsoft.com/en-us/library/dd145078(VS.85).aspx */
public static native int SetPixel(Pointer hdc, int X, int Y, int crColor);
/** http://msdn.microsoft.com/en-us/library/dd144909(VS.85).aspx */
public static native int GetPixel(Pointer hdc, int nXPos, int nYPos);
/** http://msdn.microsoft.com/en-us/library/dd183539(VS.85).aspx */
public static native boolean DeleteObject(Pointer hObject);
/** http://msdn.microsoft.com/en-us/library/dd183533(VS.85).aspx */
public static native boolean DeleteDC(Pointer hdc);
}
}
class WindowInfo
{
String title;
HWND hWnd;
Image image;
public WindowInfo(String title, HWND hWnd, Image image)
{
this.title = title;
this.hWnd = hWnd;
this.image = image;
}
}
1)'HICON.fromNative는()'* * 당신이 찾고있는하지 무엇입니까 . 네이티브 포인터를 Java HICON 인스턴스로 변환합니다. – technomage
2)'GetClassLongPtr()'이 현재 사용중인 인터페이스 매핑에 없다면, 매핑을 확장하여 누락 된 함수를 추가 할 수 있습니다. – technomage
3) Java에서 작동하도록 다른 호출을하면 일부 다른 (부분) 솔루션을 해킹하는 것보다 쉽습니다. JNA가 매핑을 제공하지 않는다면 적절한 w32 DLL에 대한 기존 매핑을 선택하거나 새로운 매핑을 확장합니다. – technomage