ラベル F# の投稿を表示しています。 すべての投稿を表示
ラベル F# の投稿を表示しています。 すべての投稿を表示

2011年8月14日日曜日

F#でキーボードフック

C#でできるらしいので、F#でもできるだろうということでやってみました。
.Net上の言語でキーボードフックしてるプログラムを載せてる色々なWebページを参考にしました。


F#のコンソールにコピペしてhook_start関数を実行すると,PrintScreenをフックするようになります。



open System

open System.Diagnostics
open System.Runtime.InteropServices

[<Literal>]
let WH_KEYBOARD_LL = 13

[<Literal>]
let HC_ACTION = 0

[<Literal>]
let WM_KEYDOWN = 0x0100

[<Literal>]
let WM_KEYUP = 0x0101

[<Literal>]
let WM_SYSKEYDOWN = 0x0104

[<Literal>]
let WM_SYSKEYUP = 0x0105

[<Literal>]
let VK_SNAPSHOT = 0x2Cu

[<StructLayout(LayoutKind.Sequential)>]
type KBDLLHOOKSTRUCT =
val vkCode : uint32
val scanCode : uint32
val flags : uint32
val time : uint32
val dwExtraInfo : uint32

type LowLevelKeyboardProc = delegate of int * nativeint * KBDLLHOOKSTRUCT ->\
nativeint

[<DllImport("kernel32.dll")>]
extern uint32 GetCurrentThreadId()

[<DllImport("kernel32.dll", SetLastError = true)>]
extern nativeint GetModuleHandle(string lpModuleName)

[<DllImport("user32.dll", SetLastError = true)>]
extern bool UnhookWindowsHookEx(nativeint hhk)

[<DllImport("user32.dll", SetLastError = true)>]
extern nativeint SetWindowsHookEx(int idhook, LowLevelKeyboardProc proc, native\
int hMod, uint32 threadId)

[<DllImport("user32.dll", SetLastError = true)>]
extern nativeint CallNextHookEx(nativeint hHook, int nCode, nativeint wParam, K\
BDLLHOOKSTRUCT lParam)

let mutable s_hook = 0n

let SetHook (proc : LowLevelKeyboardProc) =
use curProc = Process.GetCurrentProcess()
use curMod = curProc.MainModule
s_hook <- SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curMod.\
ModuleName), 0u)
if s_hook = 0n then false else true

let UnSetHook () =
if s_hook <> 0n then
if UnhookWindowsHookEx(s_hook) then
s_hook <- 0n
true
else
false
else
false

let MyHookProc (nCode : int) (wParam : nativeint) (lParam : KBDLLHOOKSTRUCT) =
if nCode = HC_ACTION then
match (int wParam, lParam.vkCode) with
| (WM_KEYDOWN, VK_SNAPSHOT) -> printf "Print Screen\n"; 1\
n
| (_, _) -> CallNextHookEx(s_hook, nCode, wParam, lParam)
else
CallNextHookEx(s_hook, nCode, wParam, lParam)

let hook_start() = SetHook(new LowLevelKeyboardProc(MyHookProc))



2011年5月18日水曜日

F#入門

F#はじめました。とりあえずFizzBuzz。

let fizzbuzz1 (tgt : int) =
[1..tgt]
|> List.map
(fun n -> if n % 15 = 0
then printf "FizzBuzz\n"
else if n % 5 = 0
then printf "Buzz\n"
else if n % 3 = 0
then printf "Fizz\n"
else printf "%d\n" n)
|> ignore

let fizzbuzz2 (tgt : int) =
[1..tgt]
|> List.iter
(fun n ->
match n with
| _ when n % 15 = 0 -> printf "FizzBuzz\n"
| _ when n % 5 = 0 -> printf "Buzz\n"
| _ when n % 3 = 0 -> printf "Fizz\n"
|_ -> printf "%d\n" n)
|> ignore

いちおうプログラミングF#は流し読みしたけれど、 9割がた抜け落ちてるのでコードを書きつつ読み直してみる。