Last active
November 24, 2016 22:32
-
-
Save CalebWhiting/af5de7db973f37ded205ff0256bac94b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * WindowHandle.cpp | |
| * | |
| * Author: Caleb Whiting | |
| */ | |
| #include "jni/org_jscrape_internal_WindowHandle.h" | |
| #include <iostream> | |
| #include <vector> | |
| #include <Windows.h> | |
| using namespace std; | |
| #define JAVA_WRAPPER "org/jscrape/internal/WindowHandle" | |
| struct JNI_ENUM_WINDOWS_PARAM { | |
| vector<jobject>* vect; | |
| JNIEnv* env; | |
| }; | |
| template<typename T> | |
| void invoke(JNIEnv* env, jobject o, jclass cls, const char* methodName, | |
| const char* signature, T arguments, ...) { | |
| jmethodID mid = env->GetMethodID(cls, methodName, signature); | |
| env->CallVoidMethod(o, mid, arguments); | |
| } | |
| void setBounds(JNIEnv* env, jobject o, jclass cls, const char* methodName, | |
| RECT b) { | |
| invoke(env, o, cls, methodName, "(IIII)V", b.top, b.right, b.bottom, | |
| b.left); | |
| } | |
| BOOL CALLBACK AddWindowToVector(HWND h, LPARAM ptr) { | |
| // Variables | |
| JNI_ENUM_WINDOWS_PARAM* param = reinterpret_cast<JNI_ENUM_WINDOWS_PARAM*>(ptr); | |
| JNIEnv* env = param->env; | |
| vector<jobject>* vect = param->vect; | |
| HDC hdc = GetDC(h); | |
| RECT windowRect; | |
| RECT clientRect; | |
| TITLEBARINFO ti; | |
| jclass cls = env->FindClass(JAVA_WRAPPER); | |
| // Check that the vector doesn't contain this process already | |
| DWORD pid; | |
| GetWindowThreadProcessId(h, &pid); | |
| for (vector<jobject>::size_type i = 0; i != vect->size(); i++) { | |
| jobject o = vect->at(i); | |
| int ppid = env->CallIntMethod(o, env -> GetMethodID(cls, "hashCode", "()I")); | |
| if (ppid == pid) { | |
| goto cleanup; | |
| } | |
| } | |
| // Create instance | |
| jmethodID construct = env->GetMethodID(cls, "<init>", "(I)V"); | |
| jobject o = env->NewObject(cls, construct, pid); | |
| // Set properties | |
| GetWindowRect(h, &windowRect); | |
| setBounds(env, o, cls, "setWindowRect", windowRect); | |
| GetClientRect(h, &clientRect); | |
| setBounds(env, o, cls, "setClientRect", clientRect); | |
| // Set Title | |
| int titleLength = GetWindowTextLength(h) + 1; | |
| TCHAR* titleText = new TCHAR[titleLength]; | |
| titleLength = GetWindowText(h, titleText, titleLength); | |
| jchar* title = new jchar[titleLength]; | |
| for (int i = 0; i < titleLength; i++) { | |
| title[i] = titleText[i]; | |
| } | |
| invoke(env, o, cls, "setTitle", "(Ljava/lang/String;)V", | |
| env->NewString(title, titleLength)); | |
| // Get TitleBarInfo | |
| if (GetTitleBarInfo(h, &ti)) { | |
| RECT tb = ti.rcTitleBar; | |
| setBounds(env, o, cls, "setTitleRect", tb); | |
| } | |
| // Push | |
| vect->push_back(o); | |
| // Cleanup | |
| cleanup: { | |
| ReleaseDC(h, hdc); | |
| DeleteDC(hdc); | |
| return true; | |
| } | |
| } | |
| /* | |
| * Class: org_jscrape_internal_WindowHandle | |
| * Method: getHandles | |
| * Signature: ()[Lorg/jscrape/internal/WindowHandle; | |
| */ | |
| JNIEXPORT jobjectArray JNICALL | |
| Java_org_jscrape_internal_WindowHandle_getHandles(JNIEnv * env, jclass c) { | |
| // Set environment for the callback | |
| // Iterate windows and add to vector | |
| vector<jobject>* vect = new vector<jobject>(); | |
| JNI_ENUM_WINDOWS_PARAM param; | |
| param.vect = vect; | |
| param.env = env; | |
| EnumWindows(&AddWindowToVector, reinterpret_cast<LPARAM>(¶m)); | |
| // Copy to JNI array | |
| jobjectArray arr = env->NewObjectArray(vect->size(), c, nullptr); | |
| for (vector<jobject>::size_type i = 0; i != vect->size(); i++) { | |
| jobject o = vect->at(i); | |
| env->SetObjectArrayElement(arr, i, o); | |
| } | |
| // Cleanup | |
| vect->clear(); | |
| delete vect; | |
| // Return | |
| return arr; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment