⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mousewheel.cpp

📁 java写的多功能文件编辑器
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////////////// Copyright (C) 2000 Davanum Srinivas (dims@geocities.com)// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// any later version.//// This program is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more// details.//// You should have received a copy of the GNU General Public License along with// this program; if not, write to the// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.///////////////////////////////////////////////////////////////////////////////#define _WIN32_WINNT (0x0400)#include <windows.h>#include <windowsx.h>#include <process.h>#include <search.h>          // for qsort and bsearch#include "JFrameEx.h"// JVM independent entry point for getting the current JVM.extern "C" {	typedef jint (JNICALL *pJNI_GetCreatedJavaVMs)(JavaVM **, jsize, jsize *);}// Thread for notifying the java code.void WINAPIV StartNotifyThread(LPVOID lpVoid);// Using arrays structures for callback mappings// MAINTENANCE NOTE:  T.Noble 10/3/2000// Removing dependency on STL removed dependency on MSVCP60.DLL, which// some people might not have (i.e. anybody running NT 4 who hasn't// installed DevStudio at some point).  Plus it decreases the size of// the DLL, which is always nice.//// This implementation should actually be faster for lookups than using// the STL map for a couple of reasons:// 1. We now cache the HWND->Proc and HWND->Frame from the last getProc//    and getFrame operation, respectively.  So the first wheel motion//    after a frame gets focus will require a lookup of the HWND mapping,//    but each subsequent wheel motion within that window uses the cached//    value.  Ref: "principle of proximity" or "principle of nearness"// 2. Using qsort each time an array element is added keeps the arrays//    in order by HWND.  Then using bsearch for the lookup is a true//    O(log(N)) complexity operation.  Note that this is equivalent to//    the map lookup in STL, since current STL implementations use//    Red/Black tree as the backing store (which is also O(log(N)) lookup).//// Note that inserts might be slightly slower for large numbers of// windows, since you incur O(N*log(N)) for the qsort, whereas insertion// into a Red/Black tree is O(log(N)).  This should be negligible compared// to the startup time of a JFrame, even if the user does have a few// thousand windows open already ;->typedef struct hwnd2object_struct {   HWND hwnd;   jobject object;} HWND2OBJECT;typedef struct hwnd2wndproc_struct {   HWND hwnd;   WNDPROC proc;} HWND2PROC;// Hopefully nobody would open more than this many windows at a time// Good luck doing so with Java and not running into problems!// If this does become a problem, then maybe make this dynamically// allocated in the future.static const int MAX_JWINDOWS=8192;// Shared Data - access to these is entirely protected by critical sectionsstatic HWND2PROC theProcArray[MAX_JWINDOWS];static HWND2OBJECT theFrameArray[MAX_JWINDOWS];static int cntFrame = 0;static int cntProc = 0;static HWND cacheFrameHwnd = 0;static jobject cacheFrameObject = 0;static HWND cacheProcHwnd = 0;static WNDPROC cacheProcProc = 0;// Critical section objects to protect shared data// Initialized/deleted in DllMainstatic CRITICAL_SECTION csProcMap;static CRITICAL_SECTION csFrameMap;// DllMain is called once with DLL_PROCESS_ATTACH when the// DLL is loaded by the process, and once with DLL_PROCESS_DETACH// when the DLL is unloaded.  Critical sections are shared by// all threads within only one process, so it's safe to initialize// and delete the critical section objects here.BOOLEAN WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){	switch (fdwReason)	{		case DLL_PROCESS_ATTACH:			// Initialize the critical sections			InitializeCriticalSection(&csProcMap);			InitializeCriticalSection(&csFrameMap);			break;		case DLL_PROCESS_DETACH:			// Clean up critical sections			DeleteCriticalSection(&csProcMap);			DeleteCriticalSection(&csFrameMap);			break;	}   return TRUE;}// Compare any two structures whose first field is an HWND// Used by qsort and bsearchint __cdecl compareHwnd (const void *elem1, const void *elem2 ){	HWND *hwnd1 = (HWND *)elem1;	HWND *hwnd2 = (HWND *)elem2;	if (*hwnd1 == *hwnd2) return 0;	if (*hwnd1 < *hwnd2) return -1;	return 1;}// Helpers for getting and storing the JFrameEx objectvoid setFrame(HWND hwnd, jobject object){	__try	{		EnterCriticalSection(&csFrameMap);		if (cntFrame < MAX_JWINDOWS)		{			theFrameArray[cntFrame].hwnd = hwnd;			theFrameArray[cntFrame++].object = object;			qsort(theFrameArray, cntFrame, sizeof(HWND2OBJECT), &compareHwnd);		}	}	__finally { LeaveCriticalSection(&csFrameMap); }}jobject getFrame(HWND hwnd){	jobject retVal = 0;	__try	{		EnterCriticalSection(&csFrameMap);		if (hwnd == cacheFrameHwnd)			retVal = cacheFrameObject;		HWND2OBJECT *h2o = (HWND2OBJECT *)bsearch(&hwnd, theFrameArray, cntFrame, sizeof(HWND2OBJECT), &compareHwnd);		if (h2o != NULL)		{			retVal = h2o->object;			cacheFrameHwnd = hwnd;			cacheFrameObject = retVal;		}	}	__finally { LeaveCriticalSection(&csFrameMap); }	return retVal;}// Helpers for getting and storing the initial window proc'svoid setProc(HWND hwnd, WNDPROC proc){	__try	{		EnterCriticalSection(&csProcMap);		if (cntProc < MAX_JWINDOWS)		{			theProcArray[cntProc].hwnd = hwnd;			theProcArray[cntProc++].proc = proc;			qsort(theProcArray, cntProc, sizeof(HWND2PROC), &compareHwnd);		}	}	__finally { LeaveCriticalSection(&csProcMap); }}WNDPROC getProc(HWND hwnd){	WNDPROC retVal = 0;	__try	{		EnterCriticalSection(&csProcMap);		if (hwnd == cacheProcHwnd)			retVal = cacheProcProc;		HWND2PROC *h2p = (HWND2PROC *)bsearch(&hwnd, theProcArray, cntProc, sizeof(HWND2PROC), &compareHwnd);		if (h2p != NULL)		{			retVal = h2p->proc;			cacheProcHwnd = hwnd;			cacheProcProc = retVal;		}	}	__finally { LeaveCriticalSection(&csProcMap); }	return retVal;}// Window Proc for subclassing.LRESULT CALLBACK FrameWindowProc(  HWND hwnd,      // handle to window  UINT uMsg,      // message identifier  WPARAM wParam,  // first message parameter  LPARAM lParam   // second message parameter){	// Get the WindowProc for this window.	WNDPROC oldProc = getProc((HWND)hwnd);	// When we get a mouse wheel message	if(uMsg == WM_MOUSEWHEEL)	{		MSG *pMsg = new MSG;		pMsg->hwnd = hwnd;		pMsg->message = uMsg;		pMsg->wParam = wParam;		pMsg->lParam = lParam;		// send it to the java code.		_beginthread(StartNotifyThread, 0, pMsg);		return 0;	}	return ::CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam);}// JNI native entry point for subclassing the windowJNIEXPORT void JNICALL Java_JFrameEx_setHook  (JNIEnv *pEnv, jobject f, jint hwnd){	// ensure that the java object can be called from any thread.	jobject frame = pEnv->NewGlobalRef(f);	WNDPROC oldProc = (WNDPROC)::SetWindowLong((HWND)hwnd, GWL_WNDPROC, (LONG)FrameWindowProc);	// store the java object	setFrame((HWND)hwnd, frame);	// store the old window proc	setProc ((HWND)hwnd, oldProc);}// JNI native entry point remving subclassing from the windowJNIEXPORT void JNICALL Java_JFrameEx_resetHook  (JNIEnv *pEnv, jobject f, jint hwnd){	WNDPROC oldProc = getProc((HWND)hwnd);	jobject frame = getFrame((HWND)hwnd);	::SetWindowLong((HWND)hwnd, GWL_WNDPROC, (LONG)oldProc);	pEnv->DeleteGlobalRef(frame);}// JVM independent helper for getting the current JVM.pJNI_GetCreatedJavaVMs getJavaVM(){	// Use the entrypoint of the current VM.	HINSTANCE hMod = ::GetModuleHandle("msjava");	if(hMod == NULL)		hMod = ::GetModuleHandle("jvm");	if(hMod == NULL)		hMod = ::GetModuleHandle("javai");	pJNI_GetCreatedJavaVMs pFunc = (pJNI_GetCreatedJavaVMs)::GetProcAddress(hMod,"JNI_GetCreatedJavaVMs");	return pFunc;}// This helper is the one that actually invokes the java JFrameEx's notifyMouseWheel methodvoid notifyMouseWheel(jobject frame,short fwKeys,short zDelta,long xPos, long yPos){	HMODULE hMod	= NULL;	JavaVM *vmBuf	= NULL;	JNIEnv *pEnv	= NULL;	jsize bufLen	= 1;	jint nVMs		= 0;	// Get the Java VM.	pJNI_GetCreatedJavaVMs pFunc = getJavaVM();	jint nRet = (*pFunc)(&vmBuf,bufLen,&nVMs);	// Attach this thread.	vmBuf->AttachCurrentThread((void **)&pEnv,NULL);	// Inform the java object that the child has been created.    jclass cls = pEnv->GetObjectClass(frame);    jmethodID mid = pEnv->GetMethodID(cls, "notifyMouseWheel", "(SSJJ)V");    if (mid == 0)        return;    pEnv->CallVoidMethod(frame, mid, (jshort)fwKeys, (jshort)zDelta, (jlong)xPos, (jlong)yPos);	// Detach this thread.	vmBuf->DetachCurrentThread();}// Helper Thread for notification.void WINAPIV StartNotifyThread(LPVOID lpVoid){	MSG *pMsg = (MSG *)lpVoid;	// This is the java object that needs to be notified.	jobject frame = getFrame(pMsg->hwnd);	// extract info from the wparam and lparam.	WPARAM fwKeys = LOWORD(pMsg->wParam);	short zDelta  = HIWORD(pMsg->wParam);	LPARAM xPos = GET_X_LPARAM(pMsg->lParam);	LPARAM yPos = GET_Y_LPARAM(pMsg->lParam);	// call the helper function.	notifyMouseWheel(frame,fwKeys,zDelta,xPos,yPos);	delete pMsg;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -