Skip to content

Instantly share code, notes, and snippets.

@RYLSnmm
Created June 19, 2017 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RYLSnmm/309258ed0782b12284aa13d725334045 to your computer and use it in GitHub Desktop.
Save RYLSnmm/309258ed0782b12284aa13d725334045 to your computer and use it in GitHub Desktop.
hide-from-taskbar: Chrome拡張機能
<!doctype html>
<meta charset="utf-8">
<script defer src="app.js"></script>
<style>
body{
margin: 0;
}
.container{
font-size: 13px;
width: 1000px;
margin: 30px auto;
}
table{
width: 100%;
border-collapse: collapse;
}
tbody tr:hover{
background: lemonchiffon;
}
td{
padding: 3px 10px;
}
input{
width: 140px;
padding: 5px 0;
background: whitesmoke;
border: 1px solid silver;
margin: 3px;
font-size: 11px;
}
</style>
<div class="container">
<table>
<thead>
<tr>
<th>hwnd</th>
<th>Title</th>
<th>Class</th>
<th></th>
</tr>
</thead>
<tbody id="table-body"></tbody>
<template id="row-template">
<tr>
<td class="hwnd"></td>
<td class="title"></td>
<td class="wclass"></td>
<td data-state="show">
<input type="button" class="show" value="タスクバーに表示する">
<br>
<input type="button" class="hide" value="タスクバーから消す">
</td>
</tr>
</template>
</table>
</div>
var $ = document.querySelector.bind(document)
var $$ = document.querySelectorAll.bind(document)
var port = chrome.runtime.connectNative("hidefromtaskbar");
port.onMessage.addListener(function(msg) {
if(msg === "ok"){
console.log(msg)
return
}
const template = $("#row-template").content
msg.trim().split("\n").sort().forEach(row => {
const clone = template.cloneNode(true)
const [hwnd, wclass, title] = row.split("\t")
clone.querySelector("tr").dataset.hwnd = hwnd
clone.querySelector(".hwnd").textContent = "0x" + ("0000000" + hwnd).substr(-8)
clone.querySelector(".title").textContent = title
clone.querySelector(".wclass").textContent = wclass
$("#table-body").append(clone)
})
})
port.onDisconnect.addListener(function() {
console.log("Disconnected");
})
port.postMessage("list")
window.onclick = eve => {
if(eve.target.matches(".show")){
confirm("タスクバーに表示しますか?") && port.postMessage("show " + eve.target.closest("tr").dataset.hwnd)
}
else if(eve.target.matches(".hide")){
confirm("タスクバーから非表示にしますか?") && port.postMessage("hide " + eve.target.closest("tr").dataset.hwnd)
}
}
window.onbeforeunload = eve => {
port.postMessage("exit")
}
// F# の詳細については、http://fsharp.org を参照してください
// 詳細については、'F# チュートリアル' プロジェクトを参照してください。
open System.Runtime.InteropServices
open System
open System.Text
open System.Collections.Generic
open System.IO
type EnumWindowsDelegate = delegate of IntPtr * IntPtr -> bool
[<DllImport("user32.dll")>]
extern [<MarshalAs(UnmanagedType.Bool)>] bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern int GetWindowTextLength(IntPtr hWnd);
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern IntPtr GetWindow(IntPtr hWnd, int uCmd)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern int GetWindowLong(IntPtr hWnd, int nIndex)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwLong)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern int ShowWindow(IntPtr handle, int command)
[<DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)>]
extern [<MarshalAs(UnmanagedType.Bool)>] bool IsWindowVisible(IntPtr hWnd)
[<Literal>]
let GW_OWNER = 4
[<Literal>]
let GWL_STYLE = -16
[<Literal>]
let GWL_EXSTYLE = -20
[<Literal>]
let SW_HIDE = 0
[<Literal>]
let SW_SHOW = 5
[<Literal>]
let WS_VISIBLE = 0x10000000
[<Literal>]
let WS_EX_APPWINDOW = 0x00040000
[<Literal>]
let WS_EX_TOOLWINDOW = 0x00000080
let log str =
File.AppendAllText("log.txt", str)
let window_list = new List<string>()
let EnumWindowCallBack (hWnd: IntPtr) (lparam: IntPtr) =
if (not (IsWindowVisible(hWnd))) || GetWindow(hWnd, GW_OWNER) <> IntPtr.Zero then
true
else
//ウィンドウのタイトルの長さを取得する
let text_len = GetWindowTextLength(hWnd)
//ウィンドウのタイトルを取得する
let tsb = new StringBuilder(text_len + 1)
GetWindowText(hWnd, tsb, tsb.Capacity) |> ignore
//ウィンドウのクラス名を取得する
let csb = new StringBuilder(256)
GetClassName(hWnd, csb, csb.Capacity) |> ignore
window_list.Add(hWnd.ToString("X8") + "\t" + csb.ToString() + "\t" + tsb.ToString())
true
let receive() =
let stdin = Console.OpenStandardInput()
let bytes: byte [] = Array.zeroCreate 4
stdin.Read(bytes, 0, 4) |> ignore
let length = BitConverter.ToInt32(bytes, 0)
let chars = [|0 .. length - 1|] |> Array.map(fun x -> ((char)(stdin.ReadByte())))
let text = String.Concat(chars)
if text = "" then
""
else
// remove quote
text.Substring(1, text.Length - 2)
let send (str: String) =
let send_str = "\"" + str.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n").Replace("\t", "\\t") + "\""
let bytes = System.Text.Encoding.UTF8.GetBytes(send_str)
let length = bytes.Length
let stdout = Console.OpenStandardOutput()
stdout.WriteByte((byte)((length >>> 0) &&& 0xFF))
stdout.WriteByte((byte)((length >>> 8) &&& 0xFF))
stdout.WriteByte((byte)((length >>> 16) &&& 0xFF))
stdout.WriteByte((byte)((length >>> 24) &&& 0xFF))
stdout.Write(bytes, 0, length)
stdout.Flush()
let getList() =
window_list.Clear()
EnumWindows(new EnumWindowsDelegate(EnumWindowCallBack), IntPtr.Zero) |> ignore
String.Join("\n", window_list)
let hide (hWnd: IntPtr) =
ShowWindow(hWnd, SW_HIDE) |> ignore
let style = GetWindowLong(hWnd, GWL_STYLE)
let new_style = style &&& ~~~(WS_VISIBLE)
SetWindowLong(hWnd, GWL_STYLE, new_style) |> ignore
let ex_style = GetWindowLong(hWnd, GWL_EXSTYLE)
let new_ex_style = ex_style ||| WS_EX_TOOLWINDOW &&& ~~~(WS_EX_APPWINDOW)
SetWindowLong(hWnd, GWL_EXSTYLE, new_ex_style) |> ignore
ShowWindow(hWnd, SW_SHOW) |> ignore
()
let show (hWnd: IntPtr) =
ShowWindow(hWnd, SW_HIDE) |> ignore
let ex_style = GetWindowLong(hWnd, GWL_EXSTYLE)
let new_ex_style = ex_style &&& ~~~(WS_EX_TOOLWINDOW) ||| WS_EX_APPWINDOW
SetWindowLong(hWnd, GWL_EXSTYLE, new_ex_style) |> ignore
let style = GetWindowLong(hWnd, GWL_STYLE)
let new_style = style ||| WS_VISIBLE
SetWindowLong(hWnd, GWL_STYLE, new_style) |> ignore
ShowWindow(hWnd, SW_SHOW) |> ignore
()
[<EntryPoint>]
let main argv =
let rec loop() =
log "wait message---\n"
let operation = receive()
log ("receive: " + operation + "\n")
if operation = "exit" || operation = "" then
()
elif operation = "list" then
send (getList())
loop()
elif operation.StartsWith("hide") then
let hex = operation.Split([|" "|], 2, StringSplitOptions.None).[1]
let hwnd = new IntPtr(Convert.ToInt64(hex, 16))
hide hwnd
send "ok"
loop()
elif operation.StartsWith("show") then
let hex = operation.Split([|" "|], 2, StringSplitOptions.None).[1]
let hwnd = new IntPtr(Convert.ToInt64(hex, 16))
show hwnd
send "ok"
loop()
else
loop()
try
loop() |> ignore
with
| ex -> log(ex.Message + "\n" + ex.StackTrace)
0
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\hidefromtaskbar]
@="C:\\path\\to\\nmh-manifest.json"
{
"manifest_version": 2,
"name": "hide-from-taskbar",
"version": "1",
"options_page": "app.html",
"permissions": [
"nativeMessaging"
]
}
{
"name": "hidefromtaskbar",
"description": "hide from taskbar",
"path": "C:\\path\\to\\hidefromtaskbar.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://EXTENSION_ID/"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment