-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
546 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,56 @@ | ||
# TypeIt | ||
<div align="center"> | ||
|
||
<!-- PROJECT LOGO --> | ||
<br /> | ||
<a href="https://github.com/valnoxy/typeit"> | ||
<img src="https://dl.exploitox.de/bucker/gh-banner-bucker-typeit.png" alt="TypeIt Banner"> | ||
</a> | ||
<br /> | ||
|
||
[![Version][version-shield]][version-url] | ||
[![Download Counter][downloads-shield]][downloads-url] | ||
[![License][license-shield]][license-url] | ||
</div> | ||
|
||
[version-shield]: https://img.shields.io/github/v/release/valnoxy/typeit?color=9565F6 | ||
[version-url]: https://github.com/valnoxy/typeit/releases | ||
|
||
[downloads-shield]: https://img.shields.io/github/downloads/valnoxy/typeit/total.svg?color=431D93 | ||
[downloads-url]: https://github.com/valnoxy/typeit/releases | ||
|
||
[license-shield]: https://img.shields.io/github/license/valnoxy/typeit?color=9565F6 | ||
[license-url]: https://img.shields.io/github/license/valnoxy/typeit | ||
|
||
<div align="center"> | ||
<h3 align="center">TypeIt</h3> | ||
<p align="center"> | ||
<p>An app that simulates and types clipboard content.</p> | ||
<a href="https://github.com/valnoxy/typeit/issues">Report Bug</a> | ||
· | ||
<a href="https://github.com/valnoxy/typeit/discussions/">Discussions</a> | ||
<br /> | ||
<br /> | ||
🎉 Version 1.0.0 is out. Check out the release notes | ||
<a href="https://github.com/valnoxy/typeit/releases">here</a>. | ||
<br /> | ||
<br /> | ||
</p> | ||
</div> | ||
|
||
--- | ||
|
||
# 🚀Introduction | ||
TypeIt is a small application for typing the clipboard using a hotkey. This can be useful for environments where CTRL-V is blocked. | ||
|
||
# 🤸 Usage | ||
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. | ||
|
||
The clipboard is typed in with the hotkey ```CTRL-B```. | ||
|
||
# 🧾 License | ||
TIelevated is licensed under [GPL-3.0](https://github.com/valnoxy/TIelevated/blob/main/LICENSE). | ||
|
||
<hr> | ||
<h6 align="center">© 2018 - 2024 valnoxy. All Rights Reserved. | ||
<br> | ||
By Jonas Günner <[email protected]></h6> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.9.34616.47 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TypeIt", "TypeIt\TypeIt.vcxproj", "{F15CAC6B-2232-441F-B08F-05263EE15BCC}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|x64 = Debug|x64 | ||
Debug|x86 = Debug|x86 | ||
Release|x64 = Release|x64 | ||
Release|x86 = Release|x86 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x64.ActiveCfg = Debug|x64 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x64.Build.0 = Debug|x64 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x86.ActiveCfg = Debug|Win32 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Debug|x86.Build.0 = Debug|Win32 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x64.ActiveCfg = Release|x64 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x64.Build.0 = Release|x64 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x86.ActiveCfg = Release|Win32 | ||
{F15CAC6B-2232-441F-B08F-05263EE15BCC}.Release|x86.Build.0 = Release|Win32 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {198EE6B5-EA2C-46CD-BEF8-1A9CDAE5ECA1} | ||
EndGlobalSection | ||
EndGlobal |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
#include <windows.h> | ||
#include <shellapi.h> | ||
#include <iostream> | ||
#include <string> | ||
#include <thread> | ||
|
||
#include "resource.h" | ||
|
||
#define WM_TRAYICON (WM_USER + 1) | ||
#define ID_TRAY_EXIT 1001 | ||
#define ID_TRAY_OPTION1 1002 | ||
#define ID_TRAY_OPTION2 1003 | ||
|
||
HINSTANCE hInst; | ||
NOTIFYICONDATA nid; | ||
HWND hWnd; | ||
bool pressEnter = true; | ||
|
||
// Read stored registry value | ||
bool ReadRegistry(const wchar_t* keyPath, const wchar_t* valueName) { | ||
HKEY hKey; | ||
DWORD dwType = REG_DWORD; | ||
DWORD dwData = 0; | ||
DWORD dwDataSize = sizeof(DWORD); | ||
|
||
LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, keyPath, 0, KEY_READ, &hKey); | ||
if (result == ERROR_SUCCESS) { | ||
result = RegQueryValueEx(hKey, valueName, nullptr, &dwType, reinterpret_cast<BYTE*>(&dwData), &dwDataSize); | ||
RegCloseKey(hKey); | ||
} | ||
|
||
return (result == ERROR_SUCCESS && dwData != 0); // Return true if value exists and is non-zero | ||
} | ||
|
||
// Write stored registry value | ||
bool WriteRegistry(bool value) { | ||
const wchar_t* keyPath = L"SOFTWARE\\valnoxy\\TypeIt"; | ||
const wchar_t* valueName = L"PressEnter"; | ||
|
||
HKEY hKey; | ||
DWORD dwDisposition; | ||
|
||
LONG result = RegCreateKeyEx( | ||
HKEY_CURRENT_USER, | ||
keyPath, | ||
0, | ||
nullptr, | ||
REG_OPTION_NON_VOLATILE, | ||
KEY_WRITE, | ||
nullptr, | ||
&hKey, | ||
&dwDisposition | ||
); | ||
|
||
if (result != ERROR_SUCCESS) { | ||
std::cerr << "Failed to create registry key." << '\n'; | ||
return false; | ||
} | ||
|
||
DWORD data = value ? 1 : 0; | ||
result = RegSetValueEx( | ||
hKey, | ||
valueName, | ||
0, | ||
REG_DWORD, | ||
reinterpret_cast<const BYTE*>(&data), | ||
sizeof(DWORD) | ||
); | ||
|
||
RegCloseKey(hKey); | ||
|
||
if (result != ERROR_SUCCESS) { | ||
std::cerr << "Failed to set registry value." << '\n'; | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
std::wstring GetClipboardText() { | ||
if (!OpenClipboard(nullptr)) { | ||
return L""; | ||
} | ||
|
||
HANDLE hData = GetClipboardData(CF_UNICODETEXT); | ||
if (hData == nullptr) { | ||
CloseClipboard(); | ||
return L""; | ||
} | ||
|
||
auto pwszText = static_cast<wchar_t*>(GlobalLock(hData)); | ||
if (pwszText == nullptr) { | ||
CloseClipboard(); | ||
return L""; | ||
} | ||
|
||
std::wstring text(pwszText); | ||
GlobalUnlock(hData); | ||
CloseClipboard(); | ||
return text; | ||
} | ||
|
||
// Simulate Keyboard Input | ||
void SimulateKeyboardInput(const std::wstring& text) { | ||
for (wchar_t c : text) { | ||
INPUT input = { 0 }; | ||
input.type = INPUT_KEYBOARD; | ||
|
||
if (c == L'\n') { | ||
input.ki.wVk = VK_RETURN; | ||
input.ki.dwFlags = 0; | ||
SendInput(1, &input, sizeof(INPUT)); | ||
input.ki.dwFlags = KEYEVENTF_KEYUP; | ||
SendInput(1, &input, sizeof(INPUT)); | ||
} | ||
else { | ||
input.ki.wVk = 0; | ||
input.ki.wScan = c; | ||
input.ki.dwFlags = KEYEVENTF_UNICODE; | ||
SendInput(1, &input, sizeof(INPUT)); | ||
input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; | ||
SendInput(1, &input, sizeof(INPUT)); | ||
} | ||
|
||
// Workaround for preventing typing too fast | ||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
} | ||
|
||
// Press Enter if option is enabled | ||
if (pressEnter) | ||
{ | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
INPUT input = { 0 }; | ||
input.type = INPUT_KEYBOARD; | ||
input.ki.wVk = VK_RETURN; | ||
input.ki.dwFlags = 0; | ||
SendInput(1, &input, sizeof(INPUT)); | ||
input.ki.dwFlags = KEYEVENTF_KEYUP; | ||
SendInput(1, &input, sizeof(INPUT)); | ||
} | ||
} | ||
|
||
// Tray Icon | ||
void CreateTrayIcon(HWND hwnd) { | ||
nid.cbSize = sizeof(NOTIFYICONDATA); | ||
nid.hWnd = hwnd; | ||
nid.uID = 1; | ||
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; | ||
nid.uCallbackMessage = WM_TRAYICON; | ||
nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)); | ||
wcscpy_s(nid.szTip, L"TypeIt"); | ||
|
||
Shell_NotifyIcon(NIM_ADD, &nid); | ||
} | ||
|
||
void ShowContextMenu(HWND hwnd) { | ||
POINT pt; | ||
GetCursorPos(&pt); | ||
HMENU hMenu = CreatePopupMenu(); | ||
if (hMenu) { | ||
// Option 1 | ||
UINT uCheck1 = (pressEnter) ? MF_CHECKED : MF_UNCHECKED; | ||
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING | uCheck1, ID_TRAY_OPTION1, L"CTRL-V + ENTER"); | ||
|
||
// Option 2 | ||
UINT uCheck2 = (!pressEnter) ? MF_CHECKED : MF_UNCHECKED; | ||
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_STRING | uCheck2, ID_TRAY_OPTION2, L"CTRL-V"); | ||
|
||
InsertMenu(hMenu, -1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr); | ||
InsertMenu(hMenu, -1, MF_BYPOSITION, ID_TRAY_EXIT, L"Exit"); | ||
|
||
// Display context menu | ||
SetForegroundWindow(hwnd); | ||
TrackPopupMenu(hMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, pt.x, pt.y, 0, hwnd, nullptr); | ||
DestroyMenu(hMenu); | ||
} | ||
} | ||
|
||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { | ||
switch (uMsg) { | ||
case WM_HOTKEY: | ||
if (wParam == 1) { | ||
std::wstring clipboardText = GetClipboardText(); | ||
SimulateKeyboardInput(clipboardText); | ||
} | ||
break; | ||
case WM_TRAYICON: | ||
if (lParam == WM_RBUTTONUP) { | ||
ShowContextMenu(hwnd); | ||
} | ||
break; | ||
case WM_COMMAND: | ||
switch (LOWORD(wParam)) { | ||
case ID_TRAY_OPTION1: | ||
pressEnter = true; | ||
WriteRegistry(true); | ||
break; | ||
case ID_TRAY_OPTION2: | ||
pressEnter = false; | ||
WriteRegistry(false); | ||
break; | ||
case ID_TRAY_EXIT: | ||
PostQuitMessage(0); | ||
break; | ||
default: | ||
break; | ||
} | ||
break; | ||
case WM_DESTROY: | ||
Shell_NotifyIcon(NIM_DELETE, &nid); | ||
PostQuitMessage(0); | ||
break; | ||
default: | ||
return DefWindowProc(hwnd, uMsg, wParam, lParam); | ||
} | ||
return 0; | ||
} | ||
|
||
// Entry Point | ||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { | ||
hInst = hInstance; | ||
WNDCLASS wc = { 0 }; | ||
|
||
wc.lpfnWndProc = WindowProc; | ||
wc.hInstance = hInstance; | ||
wc.lpszClassName = L"TypeItClass"; | ||
|
||
RegisterClass(&wc); | ||
|
||
pressEnter = ReadRegistry(L"SOFTWARE\\valnoxy\\TypeIt", L"PressEnter"); | ||
|
||
hWnd = CreateWindowEx( | ||
0, | ||
L"TypeItClass", | ||
L"TypeIt", | ||
0, | ||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | ||
nullptr, | ||
nullptr, | ||
hInstance, | ||
nullptr | ||
); | ||
|
||
if (hWnd == nullptr) { | ||
return 0; | ||
} | ||
|
||
if (!RegisterHotKey(hWnd, 1, MOD_CONTROL, 'B')) { | ||
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); | ||
return 0; | ||
} | ||
CreateTrayIcon(hWnd); | ||
|
||
MSG msg = { nullptr }; | ||
while (GetMessage(&msg, nullptr, 0, 0)) { | ||
TranslateMessage(&msg); | ||
DispatchMessage(&msg); | ||
} | ||
|
||
UnregisterHotKey(hWnd, 1); | ||
return 0; | ||
} |
Oops, something went wrong.