@armadillo-cld

Удобное написание UI на Win32 с анимациями?

В общем. Пишу UI для своего софта. Раньше делал на MFC, но надоел огромный вес. Сейчас делаю с помощью диалоговых окон и чистого Win32. Получается красиво. И вот - я решил написать свой большой проект с красивым UI и малым весом. Но уже на этапе создания интерфейса и анимаций под него я столкнулся с этим:

(Создание Subclass для отслеживания наведений на кнопки. Кнопки сделаны как STATIC, дабы придать им красивый вид)
LRESULT CALLBACK STATIC1_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC2_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); 
LRESULT CALLBACK STATIC3_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC4_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC5_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC6_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC7_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC8_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC9_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
LRESULT CALLBACK STATIC10_Subclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);


(Переменные для проверки - наведен ли курсор на определённый STATIC. Если наводится - в сабклассе элемента выставляется true на переменную, и перерисовывается. В WM_CTLCOORSTATIC проверяется эта переменная, и если она равна true - делается соответствующий фон. Тем самым создаётся анимация наведения)
bool hoverStatic1, hoverStatic2, hoverStatic3, hoverStatic4, hoverStatic5, 
	hoverStatic6, hoverStatic7, hoverStatic8, hoverStatic9, hoverStatic10 = false;
void RestoreAll() {
	if (hoverStatic1) {
		hoverStatic1 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC1), 0, 0);
	}
	if (hoverStatic2) {
		hoverStatic2 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC2), 0, 0);
	}
	if (hoverStatic3) {
		hoverStatic3 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC3), 0, 0);
	}
	if (hoverStatic4) {
		hoverStatic4 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC4), 0, 0);
	}
	if (hoverStatic5) {
		hoverStatic5 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC5), 0, 0);
	}
	if (hoverStatic6) {
		hoverStatic6 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC6), 0, 0);
	}
	if (hoverStatic7) {
		hoverStatic7 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC7), 0, 0);
	}
	if (hoverStatic8) {
		hoverStatic8 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC8), 0, 0);
	}
	if (hoverStatic9) {
		hoverStatic9 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC9), 0, 0);
	}
	if (hoverStatic10) {
		hoverStatic10 = false;
		InvalidateRect(GetDlgItem(hWnd, IDC_STATIC10), 0, 0);
	}
}


case WM_CTLCOLORSTATIC:
		{
			HDC hStatic = (HDC)wParam;

			SetTextColor(hStatic, RGB(255, 255, 255));
			SetBkMode(hStatic, TRANSPARENT);

			if (hoverStatic1 ||
				hoverStatic2 ||
				hoverStatic3 ||
				hoverStatic4 ||
				hoverStatic5 ||
				hoverStatic6 ||
				hoverStatic7 ||
				hoverStatic8 ||
				hoverStatic9 ||
				hoverStatic10)
				return (UINT)hbHoverStatic;

			return (UINT)hbDlg;
		}


И ещё очень много мусора. Как можно оптимизировать код? Уже мозги не варят после такого говнокода. Есть идейка сделать вектор, где хранить все переменные для проверки наведения, но это тоже займёт много места в коде...
  • Вопрос задан
  • 86 просмотров
Пригласить эксперта
Ответы на вопрос 2
gbg
@gbg
Баянист. Тамада. Услуги.
Свалите весь бойлерплейт (так называется тупой шаблонный код, почему так называется - топайте в вики) на автогенератор. Qt для этого использует свой генератор xml -> бойлерплейт

Собственно, есть два пути, рдин, на мой взгляд, глупый, и применяемый вендой и андроидом - это написать парсер, который будет во время выполнения приложения кушать описание формы и рисовать ее, и второй, как делает Qt (описан абзацем выше)

Первый способ ужасен тем, что парсер, работающий в рантайме без багов и дыр написать очень тяжело.
Ответ написан
Adamos
@Adamos
Вместо Qt можно использовать wxWidgets. Оно пожиже и хуже развивается, зато, если вы знаете MFC, то Виджеты покажутся вам старыми знакомыми. И они используют нативные контролы, а не собственные, как Qt, так что приложения под винду получаются и легкими, и не чужеродными.
Плюсом - про копание в винапи вы сможете забыть, как про страшный сон.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы