public class OpenOfficeReceiver : ITextReceiverInterface.ITextReceiver
{
private XTextDocument oDoc;
public void createDocument()
{
XComponentContext oStrap = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory oServMan = (XMultiServiceFactory)oStrap.getServiceManager();
XComponentLoader oDesk = (XComponentLoader)oServMan.createInstance("com.sun.star.frame.Desktop");
string url = @"private:factory/swriter";
PropertyValue[] propVals = new PropertyValue[0];
oDoc = (XTextDocument)oDesk.loadComponentFromURL(url, "_blank", 0, propVals);
}
public String giveBackTheTextContent()
{
return oDoc.getText().getString();
}
}
public class FilterLogic{
public delegate void filteredEvent();
private filteredEvent currentFilteredEvent;
private InfoDelegate infoDelegate;
private Logger logger;
public FilterLogic(InfoDelegate infoDelegate)
{
this.infoDelegate = infoDelegate;
this.logger = new Logger(infoDelegate, "FilterLogic");
}
public void setFilteredEvent(filteredEvent currentFilteredEvent){
this.currentFilteredEvent = currentFilteredEvent;
}
public void filterEnterAndApp(IntPtr a, ref Hook.KBDLLHOOKSTRUCT lParam)
{
//ENTER KEY
if (0X0D == lParam.vkCode)
{
try
{
IntPtr hwnd = APIFuncs.getforegroundWindow();
Int32 pid = APIFuncs.GetWindowProcessID(hwnd);
Process p = Process.GetProcessById(pid);
String appName = p.ProcessName;
String appltitle = APIFuncs.ActiveApplTitle().Trim().Replace("\0", "");
Console.WriteLine(appltitle);
if (appltitle != null && appltitle.Contains("Word"))
{
if (currentFilteredEvent != null)
{
currentFilteredEvent();
}
else
{
logger.logMsg(Logger.WARNINGTYPE, "there is no filteredEvent is set, so no function will be called.");
}
}
}
catch (Exception ex)
{
logger.logException(ex);
}
}
}
}
public static class Hook
{
//Similar class is on this site:
//http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx
private static class API
{
//dll imports for hooking and unhooking and sending events trough hook hierarchy
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(
int idHook,
HookDel lpfn,
IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(
IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(
IntPtr hhk,
int nCode,
IntPtr
wParam,
//IntPtr lParam);
ref KBDLLHOOKSTRUCT lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(
string lpModuleName);
}
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
int scanCode;
public int flags;
int time;
int dwExtraInfo;
}
public delegate IntPtr HookDel(
int nCode,
IntPtr wParam,
ref KBDLLHOOKSTRUCT lParam);
public delegate void KeyHandler(
IntPtr wParam,
ref KBDLLHOOKSTRUCT lParam);
private static IntPtr hhk = IntPtr.Zero;
private static HookDel hd;
private static KeyHandler kh;
//Creation of the hook
public static void CreateHook(KeyHandler _kh)
{
Console.WriteLine("CreateHook _kh: " + _kh);
Process _this = Process.GetCurrentProcess();
ProcessModule mod = _this.MainModule;
hd = HookFunc;
kh = _kh;
hhk = API.SetWindowsHookEx(13, hd, API.GetModuleHandle(mod.ModuleName), 0);
//13 is the parameter specifying that we're gonna do a low-level keyboard hook
//Console.WriteLine(Marshal.GetLastWin32Error().ToString());
//MessageBox.Show(Marshal.GetLastWin32Error().ToString()); //for debugging
//Note that this could be a Console.WriteLine(), as well. I just happened
//to be debugging this in a Windows Application
}
public static bool DestroyHook()
{
//to be called when we're done with the hook
return API.UnhookWindowsHookEx(hhk);
}
//called when key is active
private static IntPtr HookFunc(
int nCode,
IntPtr wParam,
ref KBDLLHOOKSTRUCT lParam)
{
//Console.WriteLine("nCode=" + nCode);
//Console.WriteLine("wParam=" + wParam);
int iwParam = wParam.ToInt32();
//depending on what you want to detect you can either detect keypressed or keyrealased also with a bit tweaking keyclicked.
if (nCode >= 0 && (iwParam == 0x100 ||
iwParam == 0x104)) //0x100 = WM_KEYDOWN, 0x104 = WM_SYSKEYDOWN
kh(wParam, ref lParam);
return API.CallNextHookEx(hhk, nCode, wParam, ref lParam);
}
}
class APIFuncs
{
#region Windows API Functions Declarations
//This Function is used to get Active Window Title...
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetWindowText(IntPtr hwnd, string lpString, int cch);
//This Function is used to get Handle for Active Window...
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern IntPtr GetForegroundWindow();
//This Function is used to get Active process ID...
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId);
#endregion
#region User-defined Functions
public static Int32 GetWindowProcessID(IntPtr hwnd)
{
//This Function is used to get Active process ID...
Int32 pid;
GetWindowThreadProcessId(hwnd, out pid);
return pid;
}
public static IntPtr getforegroundWindow()
{
//This method is used to get Handle for Active Window using GetForegroundWindow() method present in user32.dll
return GetForegroundWindow();
}
public static string ActiveApplTitle()
{
//This method is used to get active application's title using GetWindowText() method present in user32.dll
IntPtr hwnd = getforegroundWindow();
if (hwnd.Equals(IntPtr.Zero)) return "";
string lpText = new string((char)0, 100);
int intLength = GetWindowText(hwnd, lpText, lpText.Length);
if ((intLength <= 0) || (intLength > lpText.Length)) return "unknown";
return lpText.Trim();
}
#endregion
}
Hook.CreateHook(new Hook.KeyHandler(filterLogic.filterEnterAndApp));
Hook.DestroyHook();
Tehát a probléma: szedjük ki bizonyos időközönként egy aktuálisan megnyitott dokumentumból a szöveget. C#.NET-et találtam a legkényelmesebbnek ehhez, bár így sem volt egyszerű. Rengeteg írás van a neten, hogy hogyan bizergáljunk lementett doc fájlokat, de ritka, hogy hogyan dolgozzunk egy aktuálisan megnyitott doksival. Annyi könnyíti a helyzetemet, hogy magát a dokumentumot az elején feldobhatom én is, így nem kell kikeresnem az aktívot, hanem feltételezhetem, hogy az általam megnyitottba írnak majd. Csupán a Microsoft.Office.Core és a Microsoft.Office.Interop.Word dll-eket kell csak behúzni. A kód valami ilyesmi, persze még az ütemes giveBackTheText() hívások kellenek köré:
public class WordTextReceiver
{
private Microsoft.Office.Interop.Word.Application wordApp;
private Document doc;
public void init()
{
createWordDocument();
}
private void createWordDocument()
{
wordApp = new Microsoft.Office.Interop.Word.Application();
object readOnly = false;
object isVisible = true;
// Here is the way to handle parameters you don't care about in .NET
object missing = System.Reflection.Missing.Value;
wordApp.Visible = true;
try
{
doc = wordApp.Documents.Add(ref missing, ref missing, ref missing, ref isVisible);
}
catch (COMException ce)
{
// some logging or error handling here
}
doc.Activate();
}
public String giveBackTheText()
{
return doc.Content.Text;
}
}
Nem igazán értettem eddig, hogy milyen problémás dolog tud lenni egy kódot szépen csicsázva publikálni egy blogon. Ez tipikusan olyasvalami, mely felett átsiklik az ember, elintézi annyival magában, hogy ODA KELL KOPIPÉSZTELNI, OSZT KÉSZENVAN. De ha egy kicsit is eltűnődsz, nem is oly egyszerű. Lehetőség lenne, hogy magadnál átfuttasd a kódodat egy html+css csicsázó készüléken, és az outputot kopizod a blogbejegyzésedbe. Ez nehezen módosítható utólag, béna megoldás.
Az ultimate megoldást egy sörivó srác adja (azért kér donation-t, hogy sört vehessen), itten van az oldala: http://alexgorbatchev.com/wiki/SyntaxHighlighter. Itt meg egy srác blogja, aki leírja, hogy ezt hogy is kell használni bloggeren: http://blog.cartercole.com/2009/10/awesome-syntax-highlighting-made-easy.html.
Röviden annyi a trükk, hogy javascript+css kombóval csinálja a syntax highlight-ot, magyarul runtime az oldal betöltésekor csicsáz, így a forrásban szépen módosítható marad a kód, cserélhető a stílus. A javascript kód ingyenes hosztolása is megoldott (mivel ugye bloggerre nemnagyon tehetsz fel ilyet).
public class Allat{
private String str = "";
}