From 4cf9a3b8fe91cc0b43d0cbab51cf02c7b1f8d60d Mon Sep 17 00:00:00 2001 From: qwertfisch Date: Mon, 19 Nov 2012 21:25:24 +0000 Subject: KeyBuddy2: ein neuer Ansatz eines Layouttools, ähnlich zu NeoVars, aber in C++ geschrieben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.neo-layout.org@2431 b9310e46-f624-0410-8ea1-cfbb3a30dc96 --- windows/keybuddy2/src/hotstrings.cpp | 268 +++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 windows/keybuddy2/src/hotstrings.cpp (limited to 'windows/keybuddy2/src/hotstrings.cpp') diff --git a/windows/keybuddy2/src/hotstrings.cpp b/windows/keybuddy2/src/hotstrings.cpp new file mode 100644 index 0000000..2c5a397 --- /dev/null +++ b/windows/keybuddy2/src/hotstrings.cpp @@ -0,0 +1,268 @@ +#include "includes.h" + +hotString* hotString::pHotStrings=NULL; +int hotString::numHotStrings=0; +WString hotString::hsBuffer; +int hotString::bufferLen=0; +long hotString::lastFocusPtr=0; + +// load all hotstrings from file +void hotString::loadHotStrings(){ + + // in a first pass, just rush through the file and count the number of hotstrings + + FILE* pFile; + int i; + char buffer; + wchar unibuffer; + + #define FGETUC(pbuf,pfile) fread(pbuf,sizeof(wchar),1,pfile) + + numHotStrings=0; + bool valueEnd; + + pFile = fopen(SRCPATH "hotstrings.txt", "rb"); + if (pFile==NULL) {PromptOK("Can't read hotstrings.txt"); exit(1);} + + fgetc(pFile); // skip BOM + fgetc(pFile); + + while(!feof(pFile)){ + FGETUC(&unibuffer,pFile); // read identifier + if( unibuffer>=97 && unibuffer<=122 ){ + + FGETUC(&unibuffer,pFile); // read = + FGETUC(&unibuffer,pFile); // read " + + valueEnd=false; + while(!valueEnd){ + FGETUC(&unibuffer,pFile); + if(unibuffer==34){valueEnd=true;} // read " -> end of value + if(unibuffer==92){FGETUC(&unibuffer,pFile);} // read \ -> skip next character + } + FGETUC(&unibuffer,pFile); // read separator + if(unibuffer==13){ // line break -> entry complete + numHotStrings++; + FGETUC(&unibuffer,pFile); // read chr10 + } + } + } + + // now allocate as much memory as needed + pHotStrings = new hotString[numHotStrings]; + + // now go through in a second pass and store hotstrings + int iEntry=0; + + rewind(pFile); + + fgetc(pFile); // skip BOM + fgetc(pFile); + + WString* pTarget=NULL; + fpos_t valueStart; + int valueLength; + bool isH; + + while(!feof(pFile)){ + FGETUC(&unibuffer,pFile); // read identifier + if(feof(pFile)){break;} // sometimes the first feof didnt indicate the end, so check again after read operatio + + isH=false; + + switch(unibuffer){ + case 'h': + case 'H': + pTarget=&(hotString::pHotStrings[iEntry].hs); + isH=true; + break; + case 'c': + case 'C': + pTarget=&(hotString::pHotStrings[iEntry].winClass); + break; + case 't': + case 'T': + pTarget=&(hotString::pHotStrings[iEntry].winTitle); + break; + case 's': + case 'S': + pTarget=&(hotString::pHotStrings[iEntry].value); + hotString::pHotStrings[iEntry].launch=false; + break; + case 'l': + case 'L': + pTarget=&(hotString::pHotStrings[iEntry].value); + hotString::pHotStrings[iEntry].launch=true; + break; + default: + PromptOK("Error parsing hotstrings.txt: unknown element"); exit(1); + } + + FGETUC(&unibuffer,pFile); // read = + FGETUC(&unibuffer,pFile); // read " + + fgetpos(pFile, &valueStart); + + // read value first to determine its length, then again and store + + valueEnd=false; + valueLength=0; + while(!valueEnd){ + FGETUC(&unibuffer,pFile); + if(unibuffer==34){ // read " -> end of value + valueEnd=true; + } + else{ + if(unibuffer==92){ // read \ -> dont check next character + FGETUC(&unibuffer,pFile); + valueLength++; + } + else{ // increase number of chars + valueLength++; + } + } + } + + if(isH && valueLength>bufferLen){ + bufferLen=valueLength; + } + + *pTarget = WString(0,valueLength); + fsetpos(pFile, &valueStart); + for(i=0;i skip to next character + pTarget->Set(i,unibuffer); + } + + FGETUC(&unibuffer,pFile); // read " + FGETUC(&unibuffer,pFile); // read separator + if(unibuffer==13){ // line break -> entry complete + LOGG("Read hotstring: hs=");LOGG(pHotStrings[iEntry].hs); + LOGG(" winTitle=");LOGG(pHotStrings[iEntry].winTitle); + LOGG(" winClass=");LOGG(pHotStrings[iEntry].winClass); + LOGG(" value=");LOGG(pHotStrings[iEntry].value);LOGGNL; + iEntry++; + FGETUC(&unibuffer,pFile); // read chr10 + } + } + fclose(pFile); + + // create log buffer as long as the longest hotstring + hsBuffer = WString(0,bufferLen); + + // sort list + qsort(pHotStrings,numHotStrings,sizeof(hotString),compareHotStrings); + +} + +// compare the hotstringbuffer to all hotstrings and fire if there is a match +// to be more efficient, this could be done using a trie +// however, c++ takes very few time to compare thousands of strings, so this was +// not considered necessary +void hotString::checkHotStrings(){ + int i,k; + bool hit; + + for(i=0;i-1) ){ // ok, everything matches, fire! + + hit=true; + } + } + + if(hit){ + + for(k=0;kGetHWND(),&unused); + long otherThread=GetWindowThreadProcessId(GetForegroundWindow(),&unused); + + if(myThread!=otherThread){ + AttachThreadInput(otherThread,myThread,true); + } + + long result=(long)GetFocus(); + + if(myThread!=otherThread){ + AttachThreadInput(otherThread,myThread,false); + } + + return result; +} + +void hotString::getFocusInfo(WString& objectClass, WString& parentTitle){ + + char buffer[256]; + GetClassName((HWND)getFocusWindowPtr(),buffer,255); + objectClass=WString(buffer); + + GetWindowText(GetForegroundWindow(),buffer,255); + parentTitle=WString(buffer); +} -- cgit v1.2.3