поясните по исходнику

crause
Дата: 15.10.2014 10:20:17
как то давно нашел утилиту по замене курсора при вводе вроде как полезная штука местами.
решил пару утилит аналогичных сделать, естественно на delphi.

#define OEMRESOURCE
#include <windows.h>

HINSTANCE	g_instance;
HHOOK		g_hook;
HCURSOR		g_hc_ibeam;
UINT_PTR	g_timer = NULL;
DWORD		g_active = 0;
DWORD		g_layout = 0;

void CALLBACK UpdateTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
	if (g_active < GetTickCount())
	{
		KillTimer(0, g_timer);
		g_timer = NULL;
		g_active = 0;
		g_layout = 0;
		SetSystemCursor(CopyCursor(g_hc_ibeam), OCR_IBEAM);
	}
	else
	{
		int layout = (int) GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), NULL)) & 0xFFFF;
		if (g_layout != layout)
		{
			g_layout = layout;
			HCURSOR hc_new = LoadCursor(g_instance, MAKEINTRESOURCE(layout));
			if (hc_new)
			{
				SetSystemCursor(hc_new, OCR_IBEAM);
			}
			else
			{
				SetSystemCursor(CopyCursor(g_hc_ibeam), OCR_IBEAM);
			}
		}
	}
}

LRESULT CALLBACK LowLevelKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (nCode == HC_ACTION)
	{
		KBDLLHOOKSTRUCT *ks = (KBDLLHOOKSTRUCT*)lParam;
		if (ks->vkCode==VK_LSHIFT)
		{
			if (wParam == WM_KEYDOWN)
			{
				g_active = GetTickCount() + 10000;
				UpdateTimer(NULL, NULL, NULL, NULL);
				g_timer = SetTimer(NULL, g_timer, 100, UpdateTimer);
			}
			else if (wParam == WM_KEYUP && g_active)
			{
				g_active = GetTickCount() + 1000;
			}
		}
	}
	return CallNextHookEx(g_hook, nCode, wParam, lParam);
}

int Main()
{
	HANDLE mutex = CreateMutex(NULL, FALSE, "LangCursor");
	if (GetLastError() == ERROR_ALREADY_EXISTS || GetLastError() == ERROR_ACCESS_DENIED) return 1;

	g_hc_ibeam = CopyCursor(LoadCursor(NULL, IDC_IBEAM));
	if (!g_hc_ibeam) return 1;

	g_instance = GetModuleHandle(NULL);
	g_hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHook, g_instance, 0);
	if (!g_hook) return 1;

	MSG msg;
	while (GetMessage(&msg,0,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	
	UnhookWindowsHookEx(g_hook);
	DestroyCursor(g_hc_ibeam);
	return 0;
}

EXTERN_C void WINAPI WinMainCRTStartup()
{
	ExitProcess(Main());




- Зачем автору в исходнике mutex?
- приложение не оконное зачем тут GetMessage.... в цикле?
Dimitry Sibiryakov
Дата: 15.10.2014 10:29:38

crause
HCURSOR hc_new = LoadCursor(g_instance, MAKEINTRESOURCE(layout));
if (hc_new)
{
   SetSystemCursor(hc_new, OCR_IBEAM);
}

Ещё вопрос: что это за фигня, если в MSDN написано "The system destroys hcur by calling
the DestroyCursor function. Therefore, hcur cannot be a cursor loaded using the LoadCursor
function."?..

Posted via ActualForum NNTP Server 1.5

Dima T
Дата: 15.10.2014 10:33:16
crause
- Зачем автору в исходнике mutex?

Для зашиты от одновременного запуска нескольких копий. Первая копия создает именованный мутекс, вторая получает ошибку ERROR_ALREADY_EXISTS и завершается.
MasterZiv
Дата: 15.10.2014 10:36:56
crause
- приложение не оконное зачем тут GetMessage.... в цикле?


Отвечу сразу на второй вопрос -- GetMessage тут нужно именно потому, что приложение оконное.
Собственно, оконность приложения тем и определяется, что оно использует GetMessage.
MasterZiv
Дата: 15.10.2014 10:40:44
crause

- Зачем автору в исходнике mutex?


Чтобы контролировать запуск приложения и гарантированно иметь только один экземпляр приложения.
Т.е. повторный запуск приложения запрещается, как только выявляется, что приложение уже запущено, оно тут же завершается.
Делается это с помощью мьютекса , но это могло бы быть сделано на основе любого другого глобального объекта ядра (kernel) или GDI, на тех же принципах.
crause
Дата: 15.10.2014 10:43:25
C C++ незнаком и сейчас читаю его очень тяжело, но хотя не страшен черт так как он кажется.
Спасибо разобрался в коде вопросов стало намного меньше.
MasterZiv
Дата: 15.10.2014 10:46:16
crause
- приложение не оконное зачем тут GetMessage.... в цикле?


Тут конкретно это нужно, чтобы работал таймер и
вызывалась функция
UpdateTimer
MasterZiv
Дата: 15.10.2014 10:48:16
crause,

это очевидно не самый лучший в мире код Windows-приложения...
Можно встречный вопрос -- зачем эта хрень нужна и что она делает?
Dima T
Дата: 15.10.2014 10:49:12
crause
C C++ незнаком и сейчас читаю его очень тяжело...

Тут от Си разве что фигурные скобки :) остальное это WinAPI. Оно и в дельфях практически так же будет выглядеть.
MasterZiv
Дата: 15.10.2014 10:56:56
crause
C C++ незнаком и сейчас читаю его очень тяжело, но хотя не страшен черт так как он кажется.
Спасибо разобрался в коде вопросов стало намного меньше.


Этот код на чистом С, это не С++...