Skip to content

Commit 39ab04a

Browse files
committed
initial release
1 parent 4579f37 commit 39ab04a

File tree

8 files changed

+546
-1
lines changed

8 files changed

+546
-1
lines changed

README.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,56 @@
1-
# TypeIt
1+
<div align="center">
2+
3+
<!-- PROJECT LOGO -->
4+
<br />
5+
<a href="https://github.com/valnoxy/typeit">
6+
<img src="https://dl.exploitox.de/bucker/gh-banner-bucker-typeit.png" alt="TypeIt Banner">
7+
</a>
8+
<br />
9+
10+
[![Version][version-shield]][version-url]
11+
[![Download Counter][downloads-shield]][downloads-url]
12+
[![License][license-shield]][license-url]
13+
</div>
14+
15+
[version-shield]: https://img.shields.io/github/v/release/valnoxy/typeit?color=9565F6
16+
[version-url]: https://github.com/valnoxy/typeit/releases
17+
18+
[downloads-shield]: https://img.shields.io/github/downloads/valnoxy/typeit/total.svg?color=431D93
19+
[downloads-url]: https://github.com/valnoxy/typeit/releases
20+
21+
[license-shield]: https://img.shields.io/github/license/valnoxy/typeit?color=9565F6
22+
[license-url]: https://img.shields.io/github/license/valnoxy/typeit
23+
24+
<div align="center">
25+
<h3 align="center">TypeIt</h3>
26+
<p align="center">
27+
<p>An app that simulates and types clipboard content.</p>
28+
<a href="https://github.com/valnoxy/typeit/issues">Report Bug</a>
29+
·
30+
<a href="https://github.com/valnoxy/typeit/discussions/">Discussions</a>
31+
<br />
32+
<br />
33+
🎉 Version 1.0.0 is out. Check out the release notes
34+
<a href="https://github.com/valnoxy/typeit/releases">here</a>.
35+
<br />
36+
<br />
37+
</p>
38+
</div>
39+
40+
---
41+
42+
# 🚀Introduction
43+
TypeIt is a small application for typing the clipboard using a hotkey. This can be useful for environments where CTRL-V is blocked.
44+
45+
# 🤸 Usage
46+
Start TypeIt like any other application. At the bottom of the taskbar you will find a small icon where you can set whether ENTER should be pressed after pasting.
47+
48+
The clipboard is typed in with the hotkey ```CTRL-B```.
49+
50+
# 🧾 License
51+
TIelevated is licensed under [GPL-3.0](https://github.com/valnoxy/TIelevated/blob/main/LICENSE).
52+
53+
<hr>
54+
<h6 align="center">© 2018 - 2024 valnoxy. All Rights Reserved.
55+
<br>
56+
By Jonas Günner &lt;[email protected]&gt;</h6>

TypeIt.sln

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.9.34616.47
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TypeIt", "TypeIt\TypeIt.vcxproj", "{F15CAC6B-2232-441F-B08F-05263EE15BCC}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|x64 = Debug|x64
11+
Debug|x86 = Debug|x86
12+
Release|x64 = Release|x64
13+
Release|x86 = Release|x86
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x64.ActiveCfg = Debug|x64
17+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x64.Build.0 = Debug|x64
18+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x86.ActiveCfg = Debug|Win32
19+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x86.Build.0 = Debug|Win32
20+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x64.ActiveCfg = Release|x64
21+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x64.Build.0 = Release|x64
22+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x86.ActiveCfg = Release|Win32
23+
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x86.Build.0 = Release|Win32
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {198EE6B5-EA2C-46CD-BEF8-1A9CDAE5ECA1}
30+
EndGlobalSection
31+
EndGlobal

TypeIt/Resource.rc

5.16 KB
Binary file not shown.

TypeIt/TypeIt.cpp

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
#include <windows.h>
2+
#include <shellapi.h>
3+
#include <iostream>
4+
#include <string>
5+
#include <thread>
6+
7+
#include "resource.h"
8+
9+
#define WM_TRAYICON (WM_USER + 1)
10+
#define ID_TRAY_EXIT 1001
11+
#define ID_TRAY_OPTION1 1002
12+
#define ID_TRAY_OPTION2 1003
13+
14+
HINSTANCE hInst;
15+
NOTIFYICONDATA nid;
16+
HWND hWnd;
17+
bool pressEnter = true;
18+
19+
// Read stored registry value
20+
bool ReadRegistry(const wchar_t* keyPath, const wchar_t* valueName) {
21+
HKEY hKey;
22+
DWORD dwType = REG_DWORD;
23+
DWORD dwData = 0;
24+
DWORD dwDataSize = sizeof(DWORD);
25+
26+
LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, keyPath, 0, KEY_READ, &hKey);
27+
if (result == ERROR_SUCCESS) {
28+
result = RegQueryValueEx(hKey, valueName, nullptr, &dwType, reinterpret_cast<BYTE*>(&dwData), &dwDataSize);
29+
RegCloseKey(hKey);
30+
}
31+
32+
return (result == ERROR_SUCCESS && dwData != 0); // Return true if value exists and is non-zero
33+
}
34+
35+
// Write stored registry value
36+
bool WriteRegistry(bool value) {
37+
const wchar_t* keyPath = L"SOFTWARE\\valnoxy\\TypeIt";
38+
const wchar_t* valueName = L"PressEnter";
39+
40+
HKEY hKey;
41+
DWORD dwDisposition;
42+
43+
LONG result = RegCreateKeyEx(
44+
HKEY_CURRENT_USER,
45+
keyPath,
46+
0,
47+
nullptr,
48+
REG_OPTION_NON_VOLATILE,
49+
KEY_WRITE,
50+
nullptr,
51+
&hKey,
52+
&dwDisposition
53+
);
54+
55+
if (result != ERROR_SUCCESS) {
56+
std::cerr << "Failed to create registry key." << '\n';
57+
return false;
58+
}
59+
60+
DWORD data = value ? 1 : 0;
61+
result = RegSetValueEx(
62+
hKey,
63+
valueName,
64+
0,
65+
REG_DWORD,
66+
reinterpret_cast<const BYTE*>(&data),
67+
sizeof(DWORD)
68+
);
69+
70+
RegCloseKey(hKey);
71+
72+
if (result != ERROR_SUCCESS) {
73+
std::cerr << "Failed to set registry value." << '\n';
74+
return false;
75+
}
76+
77+
return true;
78+
}
79+
80+
std::wstring GetClipboardText() {
81+
if (!OpenClipboard(nullptr)) {
82+
return L"";
83+
}
84+
85+
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
86+
if (hData == nullptr) {
87+
CloseClipboard();
88+
return L"";
89+
}
90+
91+
auto pwszText = static_cast<wchar_t*>(GlobalLock(hData));
92+
if (pwszText == nullptr) {
93+
CloseClipboard();
94+
return L"";
95+
}
96+
97+
std::wstring text(pwszText);
98+
GlobalUnlock(hData);
99+
CloseClipboard();
100+
return text;
101+
}
102+
103+
// Simulate Keyboard Input
104+
void SimulateKeyboardInput(const std::wstring& text) {
105+
for (wchar_t c : text) {
106+
INPUT input = { 0 };
107+
input.type = INPUT_KEYBOARD;
108+
109+
if (c == L'\n') {
110+
input.ki.wVk = VK_RETURN;
111+
input.ki.dwFlags = 0;
112+
SendInput(1, &input, sizeof(INPUT));
113+
input.ki.dwFlags = KEYEVENTF_KEYUP;
114+
SendInput(1, &input, sizeof(INPUT));
115+
}
116+
else {
117+
input.ki.wVk = 0;
118+
input.ki.wScan = c;
119+
input.ki.dwFlags = KEYEVENTF_UNICODE;
120+
SendInput(1, &input, sizeof(INPUT));
121+
input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
122+
SendInput(1, &input, sizeof(INPUT));
123+
}
124+
125+
// Workaround for preventing typing too fast
126+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
127+
}
128+
129+
// Press Enter if option is enabled
130+
if (pressEnter)
131+
{
132+
std::this_thread::sleep_for(std::chrono::milliseconds(500));
133+
INPUT input = { 0 };
134+
input.type = INPUT_KEYBOARD;
135+
input.ki.wVk = VK_RETURN;
136+
input.ki.dwFlags = 0;
137+
SendInput(1, &input, sizeof(INPUT));
138+
input.ki.dwFlags = KEYEVENTF_KEYUP;
139+
SendInput(1, &input, sizeof(INPUT));
140+
}
141+
}
142+
143+
// Tray Icon
144+
void CreateTrayIcon(HWND hwnd) {
145+
nid.cbSize = sizeof(NOTIFYICONDATA);
146+
nid.hWnd = hwnd;
147+
nid.uID = 1;
148+
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
149+
nid.uCallbackMessage = WM_TRAYICON;
150+
nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1));
151+
wcscpy_s(nid.szTip, L"TypeIt");
152+
153+
Shell_NotifyIcon(NIM_ADD, &nid);
154+
}
155+
156+
void ShowContextMenu(HWND hwnd) {
157+
POINT pt;
158+
GetCursorPos(&pt);
159+
HMENU hMenu = CreatePopupMenu();
160+
if (hMenu) {
161+
// Option 1
162+
UINT uCheck1 = (pressEnter) ? MF_CHECKED : MF_UNCHECKED;
163+
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING | uCheck1, ID_TRAY_OPTION1, L"CTRL-V + ENTER");
164+
165+
// Option 2
166+
UINT uCheck2 = (!pressEnter) ? MF_CHECKED : MF_UNCHECKED;
167+
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING | uCheck2, ID_TRAY_OPTION2, L"CTRL-V");
168+
169+
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
170+
InsertMenu(hMenu, -1, MF_BYPOSITION, ID_TRAY_EXIT, L"Exit");
171+
172+
// Display context menu
173+
SetForegroundWindow(hwnd);
174+
TrackPopupMenu(hMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, nullptr);
175+
DestroyMenu(hMenu);
176+
}
177+
}
178+
179+
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
180+
switch (uMsg) {
181+
case WM_HOTKEY:
182+
if (wParam == 1) {
183+
std::wstring clipboardText = GetClipboardText();
184+
SimulateKeyboardInput(clipboardText);
185+
}
186+
break;
187+
case WM_TRAYICON:
188+
if (lParam == WM_RBUTTONUP) {
189+
ShowContextMenu(hwnd);
190+
}
191+
break;
192+
case WM_COMMAND:
193+
switch (LOWORD(wParam)) {
194+
case ID_TRAY_OPTION1:
195+
pressEnter = true;
196+
WriteRegistry(true);
197+
break;
198+
case ID_TRAY_OPTION2:
199+
pressEnter = false;
200+
WriteRegistry(false);
201+
break;
202+
case ID_TRAY_EXIT:
203+
PostQuitMessage(0);
204+
break;
205+
default:
206+
break;
207+
}
208+
break;
209+
case WM_DESTROY:
210+
Shell_NotifyIcon(NIM_DELETE, &nid);
211+
PostQuitMessage(0);
212+
break;
213+
default:
214+
return DefWindowProc(hwnd, uMsg, wParam, lParam);
215+
}
216+
return 0;
217+
}
218+
219+
// Entry Point
220+
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
221+
hInst = hInstance;
222+
WNDCLASS wc = { 0 };
223+
224+
wc.lpfnWndProc = WindowProc;
225+
wc.hInstance = hInstance;
226+
wc.lpszClassName = L"TypeItClass";
227+
228+
RegisterClass(&wc);
229+
230+
pressEnter = ReadRegistry(L"SOFTWARE\\valnoxy\\TypeIt", L"PressEnter");
231+
232+
hWnd = CreateWindowEx(
233+
0,
234+
L"TypeItClass",
235+
L"TypeIt",
236+
0,
237+
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
238+
nullptr,
239+
nullptr,
240+
hInstance,
241+
nullptr
242+
);
243+
244+
if (hWnd == nullptr) {
245+
return 0;
246+
}
247+
248+
if (!RegisterHotKey(hWnd, 1, MOD_CONTROL, 'B')) {
249+
MessageBox(nullptr, L"Failed to register hotkey! Make sure that no other application is already using the CTRL-B hotkey.", L"Error", MB_OK | MB_ICONERROR);
250+
return 0;
251+
}
252+
CreateTrayIcon(hWnd);
253+
254+
MSG msg = { nullptr };
255+
while (GetMessage(&msg, nullptr, 0, 0)) {
256+
TranslateMessage(&msg);
257+
DispatchMessage(&msg);
258+
}
259+
260+
UnregisterHotKey(hWnd, 1);
261+
return 0;
262+
}

0 commit comments

Comments
 (0)