Beispiel #1
0
INT_PTR CAttachDlg::AttachDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
	CAttachDlg* pDlg = NULL;
	if (messg == WM_INITDIALOG)
	{
		pDlg = (CAttachDlg*)lParam;
		pDlg->mh_Dlg = hDlg;
		SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)lParam);
	}
	else
	{
		pDlg = (CAttachDlg*)GetWindowLongPtr(hDlg, DWLP_USER);
	}

	if (!pDlg)
	{
		//_ASSERTE(pDlg!=NULL);
		return 0;
	}
	_ASSERTE(pDlg->mh_Dlg!=NULL);

	PatchMsgBoxIcon(hDlg, messg, wParam, lParam);

	switch (messg)
	{
		case WM_INITDIALOG:
		{
			gpConEmu->OnOurDialogOpened();

			CDynDialog::LocalizeDialog(hDlg, lng_DlgAttach);

			if (pDlg->mp_DpiAware)
			{
				pDlg->mp_DpiAware->Attach(hDlg, ghWnd, pDlg->mp_Dlg);
			}

			// Если ConEmu - AlwaysOnTop, то и диалогу нужно выставит этот флаг
			if (GetWindowLongPtr(ghWnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
				SetWindowPos(hDlg, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);

			SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon);
			SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm);
			SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon);

			// В Windows 2000 отсутствует процедура AttachConsole необходимая для этого режима
			EnableWindow(GetDlgItem(hDlg, IDC_ATTACH_ALT), (gnOsVer >= 0x501));

			HWND hList = GetDlgItem(hDlg, IDC_ATTACHLIST);
			pDlg->mh_List = hList;
			{
				LVCOLUMN col ={LVCF_WIDTH|LVCF_TEXT|LVCF_FMT, LVCFMT_LEFT, 60};
				wchar_t szTitle[64]; col.pszText = szTitle;

				ListView_SetExtendedListViewStyleEx(hList,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);
				ListView_SetExtendedListViewStyleEx(hList,LVS_EX_LABELTIP|LVS_EX_INFOTIP,LVS_EX_LABELTIP|LVS_EX_INFOTIP);

				col.cx = gpSetCls->EvalSize(pDlg->mb_IsWin64 ? 75 : 60, esf_Horizontal|esf_CanUseDpi);
				wcscpy_c(szTitle, L"PID");			ListView_InsertColumn(hList, alc_PID, &col);
				col.cx = gpSetCls->EvalSize(45, esf_Horizontal|esf_CanUseDpi); col.fmt = LVCFMT_CENTER;
				wcscpy_c(szTitle, L"Type");			ListView_InsertColumn(hList, alc_Type, &col);
				col.cx = gpSetCls->EvalSize(200, esf_Horizontal|esf_CanUseDpi); col.fmt = LVCFMT_LEFT;
				wcscpy_c(szTitle, L"Title");		ListView_InsertColumn(hList, alc_Title, &col);
				col.cx = gpSetCls->EvalSize(120, esf_Horizontal|esf_CanUseDpi);
				wcscpy_c(szTitle, L"Image name");	ListView_InsertColumn(hList, alc_File, &col);
				col.cx = gpSetCls->EvalSize(200, esf_Horizontal|esf_CanUseDpi);
				wcscpy_c(szTitle, L"Image path");	ListView_InsertColumn(hList, alc_Path, &col);
				col.cx = gpSetCls->EvalSize(90, esf_Horizontal|esf_CanUseDpi);
				wcscpy_c(szTitle, L"HWND");			ListView_InsertColumn(hList, alc_HWND, &col);
				col.cx = gpSetCls->EvalSize(200, esf_Horizontal|esf_CanUseDpi);
				wcscpy_c(szTitle, L"Class");		ListView_InsertColumn(hList, alc_Class, &col);
			}

			pDlg->mp_ProcessData = new CProcessData;

			CVConGroup::LogString(L"CAttachDlg::AttachDlgEnumWin::Begin");

			HWND hTaskBar = FindWindowEx(NULL, NULL, L"Shell_TrayWnd", NULL);
			if (hTaskBar)
				GetWindowThreadProcessId(hTaskBar, &pDlg->mn_ExplorerPID);
			else
				pDlg->mn_ExplorerPID = 0;

			EnumWindows(AttachDlgEnumWin, (LPARAM)pDlg);

			CVConGroup::LogString(L"CAttachDlg::AttachDlgEnumWin::End");

			delete pDlg->mp_ProcessData;
			pDlg->mp_ProcessData = NULL;

			AttachDlgProc(hDlg, WM_SIZE, 0, 0);

			RECT rect; GetWindowRect(hDlg, &rect);
			RECT rcCenter = CenterInParent(rect, ghWnd);
			MoveWindow(hDlg, rcCenter.left, rcCenter.top,
			           rect.right - rect.left, rect.bottom - rect.top, false);

			ShowWindow(hDlg, SW_SHOWNORMAL);

			SetFocus(hList);

			return FALSE;
		}

		case WM_SIZE:
		{
			RECT rcDlg, rcBtn, rcList, rcMode;
			::GetClientRect(hDlg, &rcDlg);
			HWND h = GetDlgItem(hDlg, IDC_ATTACHLIST);
			GetWindowRect(h, &rcList); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcList, 2);
			HWND hb = GetDlgItem(hDlg, ID_ATTACH);
			GetWindowRect(hb, &rcBtn); MapWindowPoints(NULL, hb, (LPPOINT)&rcBtn, 2);
			HWND hc = GetDlgItem(hDlg, IDC_ATTACH_ALT);
			GetWindowRect(hc, &rcMode); MapWindowPoints(NULL, hc, (LPPOINT)&rcMode, 2);
			BOOL lbRedraw = FALSE;
			MoveWindow(h,
				rcList.left, rcList.top, rcDlg.right - 2*rcList.left, rcDlg.bottom - 3*rcList.top - rcBtn.bottom, lbRedraw);
			MoveWindow(GetDlgItem(hDlg, IDC_NEWCONSOLE),
				rcList.left, rcDlg.bottom - rcList.top - rcBtn.bottom, rcBtn.right, rcBtn.bottom, lbRedraw);
			MoveWindow(GetDlgItem(hDlg, IDC_REFRESH),
				rcList.left*2 + rcBtn.right, rcDlg.bottom - rcList.top - rcBtn.bottom, rcBtn.right, rcBtn.bottom, lbRedraw);
			MoveWindow(GetDlgItem(hDlg, IDCANCEL),
				rcDlg.right - rcList.left - rcBtn.right, rcDlg.bottom - rcList.top - rcBtn.bottom, rcBtn.right, rcBtn.bottom, lbRedraw);
			MoveWindow(GetDlgItem(hDlg, ID_ATTACH),
				rcDlg.right - 2*rcList.left - 2*rcBtn.right, rcDlg.bottom - rcList.top - rcBtn.bottom, rcBtn.right, rcBtn.bottom, lbRedraw);
			MoveWindow(hc,
				rcDlg.right - 3*rcList.left - 2*rcBtn.right - rcMode.right, rcDlg.bottom - rcList.top - rcBtn.bottom + ((rcBtn.bottom - rcMode.bottom) / 2), rcMode.right, rcMode.bottom, lbRedraw);
			RedrawWindow(hDlg, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
			break;
		}

		case WM_GETMINMAXINFO:
		{
			MINMAXINFO* p = (MINMAXINFO*)lParam;
			HWND h;
			RECT rcBtn = {}, rcList = {}, rcMode = {};
			GetWindowRect((h = GetDlgItem(hDlg, ID_ATTACH)), &rcBtn); MapWindowPoints(NULL, h, (LPPOINT)&rcBtn, 2);
			GetWindowRect((h = GetDlgItem(hDlg, IDC_ATTACH_ALT)), &rcMode); MapWindowPoints(NULL, h, (LPPOINT)&rcMode, 2);
			GetWindowRect((h = GetDlgItem(hDlg, IDC_ATTACHLIST)), &rcList); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcList, 2);
			RECT rcWnd = {}, rcClient = {};
			GetWindowRect(hDlg, &rcWnd);
			::GetClientRect(hDlg, &rcClient);
			p->ptMinTrackSize.x = (rcWnd.right - rcWnd.left - rcClient.right) + 4*rcBtn.right + 8*rcList.left + rcMode.right;
			p->ptMinTrackSize.y = 6*rcBtn.bottom + 3*rcList.top;
			return 0;
		}

		case WM_NOTIFY:
		{
			LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;
			// По LMouseDblClick - выполнить аттач
			if (lpnmitem && (lpnmitem->hdr.idFrom == IDC_ATTACHLIST))
			{
				if (lpnmitem->hdr.code == (UINT)NM_DBLCLK)
				{
					PostMessage(hDlg, WM_COMMAND, ID_ATTACH, 0);

					// Если мышка над консолью - то клик (LBtnUp) может в нее провалиться, а не должен
					POINT ptCur; GetCursorPos(&ptCur);
					RECT rcWnd; GetWindowRect(ghWnd, &rcWnd);
					if (PtInRect(&rcWnd, ptCur))
					{
						gpConEmu->SetSkipMouseEvent(WM_MOUSEMOVE, WM_LBUTTONUP, 0);
					}
				}
			}
			break;
		}

		//case WM_TIMER:
		//	// Автообновление?
		//	break;

		case WM_CLOSE:
			pDlg->Close();
			break;
		case WM_DESTROY:
			if (pDlg->mp_DpiAware)
				pDlg->mp_DpiAware->Detach();
			break;

		case WM_COMMAND:
			if (HIWORD(wParam) == BN_CLICKED)
			{
				switch (LOWORD(wParam))
				{
					case IDOK: // JIC
					case ID_ATTACH:
						// Тут нужно получить инфу из списка и дернуть собственно аттач
						pDlg->OnStartAttach();
						return 1;
					case IDCANCEL:
					case IDCLOSE:
						// Просто закрыть
						pDlg->Close();
						return 1;
					case IDC_NEWCONSOLE:
						// Запрос на создание новой консоли
						PostMessage(ghWnd, WM_SYSCOMMAND, ID_NEWCONSOLE, 0);
						pDlg->Close();
						return 1;
					case IDC_REFRESH:
						// Перечитать список доступных окон/процессов
						{
							ListView_DeleteAllItems(pDlg->mh_List);
							pDlg->mp_ProcessData = new CProcessData;
							EnumWindows(AttachDlgEnumWin, (LPARAM)pDlg);
							delete pDlg->mp_ProcessData;
							pDlg->mp_ProcessData = NULL;
						}
						return 1;
				}
			}

			break;
		default:
			if (pDlg && pDlg->mp_DpiAware && pDlg->mp_DpiAware->ProcessDpiMessages(hDlg, messg, wParam, lParam))
			{
				return TRUE;
			}
	}

	return 0;
}
Beispiel #2
0
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
	CRecreateDlg* pDlg = NULL;
	if (messg == WM_INITDIALOG)
	{
		pDlg = (CRecreateDlg*)lParam;
		pDlg->mh_Dlg = hDlg;
		SetWindowLongPtr(hDlg, DWLP_USER, lParam);
	}
	else
	{
		pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER);
	}
	if (!pDlg)
	{
		return FALSE;
	}

	PatchMsgBoxIcon(hDlg, messg, wParam, lParam);

	switch (messg)
	{
		case WM_INITDIALOG:
			return pDlg->OnInitDialog(hDlg, messg, wParam, lParam);

		case (WM_APP+1):
			//TODO: Не совсем корректно, не учитывается предыдущее значение флажка
			gpConEmu->SetSkipOnFocus(false);
			return FALSE;

		case WM_CTLCOLORSTATIC:
			return pDlg->OnCtlColorStatic(hDlg, messg, wParam, lParam);

		case UM_FILL_CMDLIST:
			return pDlg->OnFillCmdList(hDlg, messg, wParam, lParam);

		case UM_USER_CONTROLS:
			return pDlg->OnUserControls(hDlg, messg, wParam, lParam);

		case WM_SYSCOMMAND:
			return pDlg->OnSysCommand(hDlg, messg, wParam, lParam);

		case WM_COMMAND:
			if (HIWORD(wParam) == BN_CLICKED)
			{
				return pDlg->OnButtonClicked(hDlg, messg, wParam, lParam);
			}
			else if ((HIWORD(wParam) == EN_SETFOCUS) && lParam)
			{
				return pDlg->OnEditSetFocus(hDlg, messg, wParam, lParam);
			}
			break;

		case WM_CLOSE:
			gpConEmu->OnOurDialogClosed();
			break;

		case WM_DESTROY:
			if (pDlg->mp_DpiAware)
				pDlg->mp_DpiAware->Detach();
			break;

		default:
			if (pDlg->mp_DpiAware && pDlg->mp_DpiAware->ProcessDpiMessages(hDlg, messg, wParam, lParam))
			{
				return TRUE;
			}
	}

	return 0;
}
Beispiel #3
0
INT_PTR WINAPI ConEmuAbout::aboutProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
	INT_PTR lRc = 0;
	if (DonateBtns_Process(hDlg, messg, wParam, lParam, lRc)
		|| EditIconHint_Process(hDlg, messg, wParam, lParam, lRc))
	{
		SetWindowLongPtr(hDlg, DWLP_MSGRESULT, lRc);
		return TRUE;
	}

	PatchMsgBoxIcon(hDlg, messg, wParam, lParam);

	switch (messg)
	{
		case WM_INITDIALOG:
		{
			gpConEmu->OnOurDialogOpened();
			mh_AboutDlg = hDlg;

			DonateBtns_Add(hDlg, pIconCtrl, IDOK);

			if (mp_DpiAware)
			{
				mp_DpiAware->Attach(hDlg, ghWnd, CDynDialog::GetDlgClass(hDlg));
			}

			RECT rect = {};
			if (GetWindowRect(hDlg, &rect))
			{
				CDpiAware::GetCenteredRect(ghWnd, rect);
				MoveWindowRect(hDlg, rect);
			}

			if ((ghOpWnd && IsWindow(ghOpWnd)) || (WS_EX_TOPMOST & GetWindowLongPtr(ghWnd, GWL_EXSTYLE)))
			{
				SetWindowPos(hDlg, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);
			}

			LPCWSTR pszActivePage = (LPCWSTR)lParam;

			wchar_t* pszTitle = lstrmerge(gpConEmu->GetDefaultTitle(), L" About");
			if (pszTitle)
			{
				SetWindowText(hDlg, pszTitle);
				SafeFree(pszTitle);
			}

			if (hClassIcon)
			{
				SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon);
				SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)CreateNullIcon());
				SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon);
			}

			SetDlgItemText(hDlg, stConEmuAbout, pAboutTitle);
			SetDlgItemText(hDlg, stConEmuUrl, gsHomePage);

			EditIconHint_Set(hDlg, GetDlgItem(hDlg, tAboutSearch), true, L"Search", false, UM_SEARCH, IDOK);
			EditIconHint_Subclass(hDlg);

			wchar_t* pszLabel = GetDlgItemTextPtr(hDlg, stConEmuVersion);
			if (pszLabel)
			{
				wchar_t* pszSet = NULL;

				if (gpUpd)
				{
					wchar_t* pszVerInfo = gpUpd->GetCurVerInfo();
					if (pszVerInfo)
					{
						pszSet = lstrmerge(pszLabel, L" ", pszVerInfo);
						free(pszVerInfo);
					}
				}

				if (!pszSet)
				{
					pszSet = lstrmerge(pszLabel, L" ", L"Please check for updates manually");
				}

				if (pszSet)
				{
					SetDlgItemText(hDlg, stConEmuVersion, pszSet);
					free(pszSet);
				}

				free(pszLabel);
			}

			HWND hTab = GetDlgItem(hDlg, tbAboutTabs);
			INT_PTR nPage = -1;

			for (size_t i = 0; i < countof(Pages); i++)
			{
				TCITEM tie = {};
				tie.mask = TCIF_TEXT;
				tie.pszText = (LPWSTR)Pages[i].Title;
				TabCtrl_InsertItem(hTab, i, &tie);

				if (pszActivePage && (lstrcmpi(pszActivePage, Pages[i].Title) == 0))
					nPage = i;
			}


			if (nPage >= 0)
			{
				TabSelected(hDlg, nPage);
				TabCtrl_SetCurSel(hTab, (int)nPage);
			}
			else if (!pszActivePage)
			{
				TabSelected(hDlg, 0);
			}
			else
			{
				_ASSERTE(pszActivePage==NULL && "Unknown page name?");
			}

			SetFocus(hTab);

			return FALSE;
		}

		case WM_CTLCOLORSTATIC:
			if (GetWindowLongPtr((HWND)lParam, GWLP_ID) == stConEmuUrl)
			{
				SetTextColor((HDC)wParam, GetSysColor(COLOR_HOTLIGHT));
				HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE);
				SetBkMode((HDC)wParam, TRANSPARENT);
				return (INT_PTR)hBrush;
			}
			else
			{
				SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
				HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE);
				SetBkMode((HDC)wParam, TRANSPARENT);
				return (INT_PTR)hBrush;
			}
			break;

		case WM_SETCURSOR:
			{
				if (GetWindowLongPtr((HWND)wParam, GWLP_ID) == stConEmuUrl)
				{
					SetCursor(LoadCursor(NULL, IDC_HAND));
					SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE);
					return TRUE;
				}
				return FALSE;
			}
			break;

		case WM_COMMAND:
			switch (HIWORD(wParam))
			{
			case BN_CLICKED:
				switch (LOWORD(wParam))
				{
					case IDOK:
					case IDCANCEL:
					case IDCLOSE:
						aboutProc(hDlg, WM_CLOSE, 0, 0);
						return 1;
					case stConEmuUrl:
						ConEmuAbout::OnInfo_HomePage();
						return 1;
				} // BN_CLICKED
				break;
			case EN_SETFOCUS:
				switch (LOWORD(wParam))
				{
				case tAboutText:
					{
						// Do not autosel all text
						HWND hEdit = (HWND)lParam;
						DWORD nStart = 0, nEnd = 0;
						SendMessage(hEdit, EM_GETSEL, (WPARAM)&nStart, (LPARAM)&nEnd);
						if (nStart != nEnd)
						{
							SendMessage(hEdit, EM_SETSEL, nTextSelStart, nTextSelEnd);
						}
					}
					break;
				}
			} // switch (HIWORD(wParam))
			break;

		case WM_NOTIFY:
		{
			LPNMHDR nmhdr = (LPNMHDR)lParam;
			if ((nmhdr->code == TCN_SELCHANGE) && (nmhdr->idFrom == tbAboutTabs))
			{
				int iPage = TabCtrl_GetCurSel(nmhdr->hwndFrom);
				if ((iPage >= 0) && (iPage < (int)countof(Pages)))
					TabSelected(hDlg, iPage);
			}
			break;
		}

		case UM_SEARCH:
			searchProc(hDlg, (HWND)lParam, false);
			break;

		case UM_EDIT_KILL_FOCUS:
			SendMessage((HWND)lParam, EM_GETSEL, (WPARAM)&nTextSelStart, (LPARAM)&nTextSelEnd);
			break;

		case WM_CLOSE:
			//if (ghWnd == NULL)
			gpConEmu->OnOurDialogClosed();
			if (mp_DpiAware)
				mp_DpiAware->Detach();
			EndDialog(hDlg, IDOK);
			//else
			//	DestroyWindow(hDlg);
			break;

		case WM_DESTROY:
			mh_AboutDlg = NULL;
			break;

		default:
			if (mp_DpiAware && mp_DpiAware->ProcessDpiMessages(hDlg, messg, wParam, lParam))
			{
				return TRUE;
			}
	}

	return FALSE;
}
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
#define UM_USER_CONTROLS (WM_USER+121)
#define UM_FILL_CMDLIST (WM_USER+122)

	CRecreateDlg* pDlg = NULL;
	if (messg == WM_INITDIALOG)
	{
		pDlg = (CRecreateDlg*)lParam;
		pDlg->mh_Dlg = hDlg;
		SetWindowLongPtr(hDlg, DWLP_USER, lParam);
	}
	else
	{
		pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER);
	}
	if (!pDlg)
	{
		return FALSE;
	}

	PatchMsgBoxIcon(hDlg, messg, wParam, lParam);

	switch (messg)
	{
		case WM_INITDIALOG:
		{
			LRESULT lbRc = FALSE;

			// Visual
			SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon);
			SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm);

			// Set password style (avoid "bars" on some OS)
			SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0);


			// Add menu items
			HMENU hSysMenu = GetSystemMenu(hDlg, FALSE);
			InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0);
			InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED,
					   ID_RESETCMDHISTORY, L"Clear history...");
			InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED
					   | (gpSet->isSaveCmdHistory ? MF_CHECKED : 0),
					   ID_STORECMDHISTORY, L"Store history");
			
			



			//#ifdef _DEBUG
			//SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE);
			//#endif

			RConStartArgs* pArgs = pDlg->mp_Args;
			_ASSERTE(pArgs);

			// Fill command and task drop down
			SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0);

			// Set text in command and folder fields
			SetDlgItemText(hDlg, IDC_RESTART_CMD, pDlg->mpsz_DefCmd ? pDlg->mpsz_DefCmd : pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : L"");
			SetDlgItemText(hDlg, IDC_STARTUP_DIR, pDlg->mpsz_DefDir ? pDlg->mpsz_DefDir : pArgs->pszStartupDir ? pArgs->pszStartupDir : gpConEmu->WorkDir());

			// Split controls
			if (pArgs->aRecreate == cra_RecreateTab)
			{
				// Hide Split's
				ShowWindow(GetDlgItem(hDlg, gbRecreateSplit), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, rbRecreateSplitNone), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Right), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Bottom), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, stRecreateSplit), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, tRecreateSplit), SW_HIDE);
			}
			else
			{
				// Fill splits
				SetDlgItemInt(hDlg, tRecreateSplit, (1000-pArgs->nSplitValue)/10, FALSE);
				CheckRadioButton(hDlg, rbRecreateSplitNone, rbRecreateSplit2Bottom, rbRecreateSplitNone+pArgs->eSplit);
				EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone));
				EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone));
			}

			// Спрятать флажок "New window"
			bool bRunInNewWindow_Hidden = (pArgs->aRecreate == cra_EditTab || pArgs->aRecreate == cra_RecreateTab);
			ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), bRunInNewWindow_Hidden ? SW_HIDE : SW_SHOWNORMAL);


			const wchar_t *pszUser = pArgs->pszUserName;
			const wchar_t *pszDomain = pArgs->pszDomain;
			bool bResticted = (pArgs->RunAsRestricted == crb_On);
			int nChecked = rbCurrentUser;
			DWORD nUserNameLen = countof(pDlg->ms_CurUser);

			if (!GetUserName(pDlg->ms_CurUser, &nUserNameLen)) pDlg->ms_CurUser[0] = 0;

			wchar_t szRbCaption[MAX_PATH*3];
			lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser
							lstrcpyn(szOtherUser, pszUser, MAX_PATH);
							wcscat_c(szOtherUser, L"@");
							lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszDomain, MAX_PATH);
						}
						else
						{
							// "Старая" нотация domain\user
							lstrcpyn(szOtherUser, pszDomain, MAX_PATH);
							wcscat_c(szOtherUser, L"\\");
							lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszUser, MAX_PATH);
						}
					}
					else
					{
						lstrcpyn(szOtherUser, pszUser, countof(szOtherUser));
					}

					SetDlgItemText(hDlg, tRunAsPassword, pArgs->szUserPassword);
				}
			}

			SetDlgItemText(hDlg, tRunAsUser, (nChecked == rbAnotherUser) ? szOtherUser : L"");
			CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked);
			RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0);

			if (gOSVer.dwMajorVersion < 6)
			{
				// В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля
				//apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE);
				SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается
				// И уменьшить длину
				RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox);
				SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top,
				             SWP_NOMOVE|SWP_NOZORDER);
			}
			else if (gpConEmu->mb_IsUacAdmin || (pArgs && (pArgs->RunAsAdministrator == crb_On)))
			{
				CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED);

				if (gpConEmu->mb_IsUacAdmin)  // Только в Vista+ если GUI уже запущен под админом
				{
					EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE);
				}
				else if (gOSVer.dwMajorVersion < 6)
				{
					RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0);
				}
			}

			//}
			SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon);

			RECT rcBtnBox = {0};
			if (pArgs->aRecreate == cra_RecreateTab)
			{
				//GCC hack. иначе не собирается
				SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to restart console");
				SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0);
				// Выровнять флажок по кнопке
				GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox);
				lbRc = TRUE;
			}
			else
			{
				//GCC hack. иначе не собирается
				SetDlgItemTextA(hDlg, IDC_RESTART_MSG,  "Create new console");

				// Если ВЫКЛЮЧЕН "Multi consoles in one window"
				// - Check & Disable "New window" checkbox
				CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow || !gpSetCls->IsMulti()) ? BST_CHECKED : BST_UNCHECKED);
				EnableWindow(GetDlgItem(hDlg, cbRunInNewWindow), gpSetCls->IsMulti());

				//
				SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0);
				POINT pt = {0,0};
				MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1);
				DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE));
				SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER);
				SetDlgItemText(hDlg, IDC_START, (pArgs->aRecreate == cra_EditTab) ? L"&Save" : L"&Start");
				DestroyWindow(GetDlgItem(hDlg, IDC_WARNING));
				// Выровнять флажок по кнопке
				GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox);
			}

			if (rcBtnBox.left)
			{
				// Выровнять флажок по кнопке
				MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2);
				RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox);
				POINT pt;
				pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5;
				pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2;
				SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER);
			}

			// Correct cbRunInNewWindow position
			if (!bRunInNewWindow_Hidden)
			{
				POINT pt = {};
				MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1);
				RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2);
				SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL,
					pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE);
			}


			// Ensure, it will be "on screen"
			RECT rect; GetWindowRect(hDlg, &rect);
			RECT rcCenter = CenterInParent(rect, pDlg->mh_Parent);
			MoveWindow(hDlg, rcCenter.left, rcCenter.top,
			           rect.right - rect.left, rect.bottom - rect.top, false);


			// Была отключена обработка CConEmuMain::OnFocus (лишние телодвижения)
			PostMessage(hDlg, (WM_APP+1), 0,0);


			// Default focus control
			if (pArgs->aRecreate == cra_RecreateTab)
				SetFocus(GetDlgItem(hDlg, IDC_START)); // Win+~ (Recreate tab), Focus on "Restart" button"
			else if ((pArgs->pszUserName && *pArgs->pszUserName) && !*pArgs->szUserPassword)
				SetFocus(GetDlgItem(hDlg, tRunAsPassword)); // We need password, all other fields are ready
			else
				SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); // Set focus in command-line field

			return lbRc;
		}
		case (WM_APP+1):
			//TODO: Не совсем корректно, не учитывается предыдущее значение флажка
			gpConEmu->SetSkipOnFocus(false);
			return FALSE;
		case WM_CTLCOLORSTATIC:

			if (GetDlgItem(hDlg, IDC_WARNING) == (HWND)lParam)
			{
				SetTextColor((HDC)wParam, 255);
				HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE);
				SetBkMode((HDC)wParam, TRANSPARENT);
				return (INT_PTR)hBrush;
			}

			break;
		//case WM_GETICON:

		//	if (wParam==ICON_BIG)
		//	{
		//		/*SetWindowLong(hWnd2, DWL_MSGRESULT, (LRESULT)hClassIcon);
		//		return 1;*/
		//	}
		//	else
		//	{
		//		SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LRESULT)hClassIconSm);
		//		return 1;
		//	}

		//	return 0;

		case UM_FILL_CMDLIST:
		{
			RConStartArgs* pArgs = pDlg->mp_Args;
			_ASSERTE(pArgs);

			pDlg->AddCommandList(pArgs->pszSpecialCmd);
			pDlg->AddCommandList(pDlg->mpsz_SysCmd, pArgs->pszSpecialCmd ? -1 : 0);
			pDlg->AddCommandList(pDlg->mpsz_CurCmd);
			pDlg->AddCommandList(pDlg->mpsz_DefCmd);

			// Может быть позван после очистки истории из меню, тогда нет смысла и дергаться
			if (wParam)
			{
				LPCWSTR pszHistory = gpSet->HistoryGet();

				if (pszHistory)
				{
					while (*pszHistory)
					{
						pDlg->AddCommandList(pszHistory);

						pszHistory += _tcslen(pszHistory)+1;
					}
				}
			}

			// Tasks
			int nGroup = 0;
			const Settings::CommandTasks* pGrp = NULL;
			while ((pGrp = gpSet->CmdTaskGet(nGroup++)))
			{
				pDlg->AddCommandList(pGrp->pszName);
			}
		}
		return 0;

		case UM_USER_CONTROLS:
		{
			if (SendDlgItemMessage(hDlg, rbCurrentUser, BM_GETCHECK, 0, 0))
			{
				EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), TRUE);
				//BOOL lbText = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) == 0;
				EnableWindow(GetDlgItem(hDlg, tRunAsUser), FALSE);
				EnableWindow(GetDlgItem(hDlg, tRunAsPassword), FALSE);
			}
			else
			{
				if (SendDlgItemMessage(hDlg, tRunAsUser, CB_GETCOUNT, 0, 0) == 0)
				{
					DWORD dwLevel = 3, dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0;
					NET_API_STATUS nStatus;
					USER_INFO_3 *info = NULL;
					nStatus = ::NetUserEnum(NULL, dwLevel, FILTER_NORMAL_ACCOUNT, (PBYTE*) & info,
					                        MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);

					if (nStatus == NERR_Success)
					{
						wchar_t *pszAdmin = NULL, *pszLikeAdmin = NULL, *pszOtherUser = NULL;

						for (DWORD i = 0; i < dwEntriesRead; ++i)
						{
							// usri3_logon_server	"\\*"	wchar_t *
							if (!(info[i].usri3_flags & UF_ACCOUNTDISABLE) && info[i].usri3_name && *info[i].usri3_name)
							{
								SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)info[i].usri3_name);

								if (info[i].usri3_priv == 2/*USER_PRIV_ADMIN*/)
								{
									if (!pszAdmin && (info[i].usri3_user_id == 500))
										pszAdmin = lstrdup(info[i].usri3_name);
									else if (!pszLikeAdmin && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0))
										pszLikeAdmin = lstrdup(info[i].usri3_name);
								}
								else if (!pszOtherUser
									&& (info[i].usri3_priv == 1/*USER_PRIV_USER*/)
									&& (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0))
								{
									pszOtherUser = lstrdup(info[i].usri3_name);
								}
							}
						}

						if (GetWindowTextLength(GetDlgItem(hDlg, tRunAsUser)) == 0)
						{
							// Try to suggest "Administrator" account
							SetDlgItemText(hDlg, tRunAsUser, pszAdmin ? pszAdmin : pszLikeAdmin ? pszLikeAdmin : pszOtherUser ? pszOtherUser : pDlg->ms_CurUser);
						}

						::NetApiBufferFree(info);
						SafeFree(pszAdmin);
						SafeFree(pszLikeAdmin);
					}
					else
					{
						// Добавить хотя бы текущего
						SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)pDlg->ms_CurUser);
					}
				}

				EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), FALSE);
				EnableWindow(GetDlgItem(hDlg, tRunAsUser), TRUE);
				EnableWindow(GetDlgItem(hDlg, tRunAsPassword), TRUE);
			}

			if (wParam == rbAnotherUser)
				SetFocus(GetDlgItem(hDlg, tRunAsUser));
		}
		return 0;

		case WM_SYSCOMMAND:
			switch (LOWORD(wParam))
			{
			case ID_RESETCMDHISTORY:
				// Подтверждение спросит ResetCmdHistory
				if (gpSetCls->ResetCmdHistory(hDlg))
				{
                	wchar_t* pszCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD);
                	SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_RESETCONTENT, 0,0);
                	SendMessage(hDlg, UM_FILL_CMDLIST, FALSE, 0);
                	if (pszCmd)
                	{
                		SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd);
                		free(pszCmd);
                	}
				}
				SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
				return 1;
			case ID_STORECMDHISTORY:
				if (MsgBox(gpSet->isSaveCmdHistory ? L"Do you want to disable history?" : L"Do you want to enable history?", MB_YESNO|MB_ICONQUESTION, NULL, hDlg) == IDYES)
				{
					gpSetCls->SetSaveCmdHistory(!gpSet->isSaveCmdHistory);
					HMENU hSysMenu = GetSystemMenu(hDlg, FALSE);
					CheckMenuItem(hSysMenu, ID_STORECMDHISTORY, MF_BYCOMMAND|(gpSet->isSaveCmdHistory ? MF_CHECKED : 0));
				}
				SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
				return 1;
			}
			break;

		case WM_COMMAND:

			if (HIWORD(wParam) == BN_CLICKED)
			{
				switch (LOWORD(wParam))
				{
					case IDC_CHOOSE:
					{
						wchar_t *pszFilePath = SelectFile(L"Choose program to run", NULL, hDlg, L"Executables (*.exe)\0*.exe\0All files (*.*)\0*.*\0\0", true, false, false);
						if (pszFilePath)
						{
							SetDlgItemText(hDlg, IDC_RESTART_CMD, pszFilePath);
							SafeFree(pszFilePath);
						}
						return 1;
					}
					case IDC_CHOOSE_DIR:
					{
						wchar_t* pszDefFolder = GetDlgItemText(hDlg, IDC_STARTUP_DIR);
						wchar_t* pszFolder = SelectFolder(L"Choose startup directory", pszDefFolder, hDlg, false, false);
						if (pszFolder)
						{
							SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszFolder);
							SafeFree(pszFolder);
						}
						SafeFree(pszDefFolder);
						return 1;
					}
					case cbRunAsAdmin:
					{
						// BCM_SETSHIELD = 5644
						BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0);

						if (gOSVer.dwMajorVersion >= 6)
						{
							SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs && (pDlg->mp_Args->aRecreate != cra_EditTab));
						}

						if (bRunAs)
						{
							CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser);
							CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED);
							RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0);
						}

						return 1;
					}
					case rbCurrentUser:
					case rbAnotherUser:
					case cbRunAsRestricted:
					{
						RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0);
						return 1;
					}
					case rbRecreateSplitNone:
					case rbRecreateSplit2Right:
					case rbRecreateSplit2Bottom:
					{
						RConStartArgs* pArgs = pDlg->mp_Args;
						switch (LOWORD(wParam))
						{
						case rbRecreateSplitNone:
							pArgs->eSplit = RConStartArgs::eSplitNone; break;
						case rbRecreateSplit2Right:
							pArgs->eSplit = RConStartArgs::eSplitHorz; break;
						case rbRecreateSplit2Bottom:
							pArgs->eSplit = RConStartArgs::eSplitVert; break;
						}
						EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone));
						EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone));
						if (pArgs->eSplit != pArgs->eSplitNone)
							SetFocus(GetDlgItem(hDlg, tRecreateSplit));
						return 1;
					}
					case IDC_START:
					{
						RConStartArgs* pArgs = pDlg->mp_Args;
						_ASSERTE(pArgs);
						SafeFree(pArgs->pszUserName);
						SafeFree(pArgs->pszDomain);

						//SafeFree(pArgs->pszUserPassword);
						if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0))
						{
							pArgs->RunAsRestricted = crb_Off;
							pArgs->pszUserName = GetDlgItemText(hDlg, tRunAsUser);

							if (pArgs->pszUserName)
							{
								//pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword);
								// Попытаться проверить правильность введенного пароля и возможность запуска
								bool bCheckPwd = pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword));
								DWORD nErr = bCheckPwd ? 0 : GetLastError();
								if (!bCheckPwd)
								{
									DisplayLastError(L"Invalid user name or password was specified!", nErr, MB_ICONSTOP, NULL, hDlg);
									return 1;
								}
							}
						}
						else
						{
							pArgs->RunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) ? crb_On : crb_Off;
						}

						// Vista+ (As Admin...)
						pArgs->RunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0) ? crb_On : crb_Off;

						// StartupDir (may be specified as argument)
						wchar_t* pszDir = GetDlgItemText(hDlg, IDC_STARTUP_DIR);
						wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL;
						LPCWSTR pszDirResult = pszExpand ? pszExpand : pszDir;
						// Another user? We may fail with access denied. Check only for "current user" account
						if (!pArgs->pszUserName && pszDirResult && *pszDirResult && !DirectoryExists(pszDirResult))
						{
							wchar_t* pszErrInfo = lstrmerge(L"Specified directory does not exists!\n", pszDirResult, L"\n" L"Do you want to choose another directory?\n\n");
							DWORD nErr = GetLastError();
							int iDirBtn = DisplayLastError(pszErrInfo, nErr, MB_ICONEXCLAMATION|MB_YESNO, NULL, hDlg);
							if (iDirBtn == IDYES)
							{
								SafeFree(pszDir);
								SafeFree(pszExpand);
								SafeFree(pszErrInfo);
								return 1;
							}
							// User want to run "as is". Most likely it will fail, but who knows...
						}
						SafeFree(pArgs->pszStartupDir);
						pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir;
						if (pszExpand)
						{
							SafeFree(pszDir)
						}

						// Command
						// pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода
						SafeFree(pArgs->pszSpecialCmd);

						// GetDlgItemText выделяет память через calloc
						pArgs->pszSpecialCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD);

						if (pArgs->pszSpecialCmd)
							gpSet->HistoryAdd(pArgs->pszSpecialCmd);

						if ((pArgs->aRecreate != cra_RecreateTab) && (pArgs->aRecreate != cra_EditTab))
						{
							if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0))
								pArgs->aRecreate = cra_CreateWindow;
							else
								pArgs->aRecreate = cra_CreateTab;
						}
						if (((pArgs->aRecreate == cra_CreateTab) || (pArgs->aRecreate == cra_EditTab))
							&& (pArgs->eSplit != RConStartArgs::eSplitNone))
						{
							BOOL bOk = FALSE;
							int nPercent = GetDlgItemInt(hDlg, tRecreateSplit, &bOk, FALSE);
							if (bOk && (nPercent >= 1) && (nPercent <= 99))
							{
								pArgs->nSplitValue = (100-nPercent) * 10;
							}						
							//pArgs->nSplitPane = 0; Сбрасывать не будем?
						}
						pDlg->mn_DlgRc = IDC_START;
						EndDialog(hDlg, IDC_START);
						return 1;
					}
					case IDC_TERMINATE:
						pDlg->mn_DlgRc = IDC_TERMINATE;
						EndDialog(hDlg, IDC_TERMINATE);
						return 1;
					case IDCANCEL:
						pDlg->mn_DlgRc = IDCANCEL;
						EndDialog(hDlg, IDCANCEL);
						return 1;
				}
			}
			else if ((HIWORD(wParam) == EN_SETFOCUS) && lParam)
			{
				switch (LOWORD(wParam))
				{
				case tRecreateSplit:
				case tRunAsPassword:
					PostMessage((HWND)lParam, EM_SETSEL, 0, SendMessage((HWND)lParam, WM_GETTEXTLENGTH, 0,0));
					break;
				}
			}

			break;
		default:
			return 0;
	}
INT_PTR WINAPI ConEmuAbout::aboutProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
	static struct {LPCWSTR Title; LPCWSTR Text;} Pages[] =
	{
		{L"About", pAbout},
		{L"Command line", pCmdLine},
		{L"Tasks", pAboutTasks},
		{L"-new_console", pNewConsoleHelpFull},
		{L"Console", pConsoleHelpFull},
		{L"Macro", pGuiMacro},
		{L"DosBox", pDosBoxHelpFull},
		{L"Contributors", pAboutContributors},
		{L"License", pAboutLicense},
	};

	INT_PTR lRc = 0;
	if (DonateBtns_Process(hDlg, messg, wParam, lParam, lRc))
	{
		SetWindowLongPtr(hDlg, DWLP_MSGRESULT, lRc);
		return TRUE;
	}

	PatchMsgBoxIcon(hDlg, messg, wParam, lParam);

	switch (messg)
	{
		case WM_INITDIALOG:
		{
			gpConEmu->OnOurDialogOpened();
			mh_AboutDlg = hDlg;

			if ((ghOpWnd && IsWindow(ghOpWnd)) || (WS_EX_TOPMOST & GetWindowLongPtr(ghWnd, GWL_EXSTYLE)))
			{
				SetWindowPos(hDlg, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);
			}

			LPCWSTR pszActivePage = (LPCWSTR)lParam;

			wchar_t* pszTitle = lstrmerge(gpConEmu->GetDefaultTitle(), L" About");
			if (pszTitle)
			{
				SetWindowText(hDlg, pszTitle);
				SafeFree(pszTitle);
			}

			if (hClassIcon)
			{
				SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon);
				SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm);
				SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon);
			}

			SetDlgItemText(hDlg, stConEmuAbout, pAboutTitle);
			SetDlgItemText(hDlg, stConEmuUrl, gsHomePage);

			DonateBtns_Add(hDlg, pIconCtrl, IDOK);

			HWND hTab = GetDlgItem(hDlg, tbAboutTabs);
			size_t nPage = 0;

			for (size_t i = 0; i < countof(Pages); i++)
			{
				TCITEM tie = {};
				tie.mask = TCIF_TEXT;
				tie.pszText = (LPWSTR)Pages[i].Title;
				TabCtrl_InsertItem(hTab, i, &tie);

				if (pszActivePage && (lstrcmpi(pszActivePage, Pages[i].Title) == 0))
					nPage = i;
			}

			SetDlgItemText(hDlg, tAboutText, Pages[nPage].Text);

			if (nPage != 0)
			{
				TabCtrl_SetCurSel(hTab, (int)nPage);
			}
			else
			{
				_ASSERTE(pszActivePage==NULL && "Unknown page name?");
			}

			SetFocus(hTab);

			return FALSE;
		}

		case WM_CTLCOLORSTATIC:
			if (GetWindowLongPtr((HWND)lParam, GWLP_ID) == stConEmuUrl)
			{
				SetTextColor((HDC)wParam, GetSysColor(COLOR_HOTLIGHT));
				HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE);
				SetBkMode((HDC)wParam, TRANSPARENT);
				return (INT_PTR)hBrush;
			}
			else
			{
				SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
				HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE);
				SetBkMode((HDC)wParam, TRANSPARENT);
				return (INT_PTR)hBrush;
			}
			break;

		case WM_SETCURSOR:
			{
				if (GetWindowLongPtr((HWND)wParam, GWLP_ID) == stConEmuUrl)
				{
					SetCursor(LoadCursor(NULL, IDC_HAND));
					SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE);
					return TRUE;
				}
				return FALSE;
			}
			break;

		case WM_COMMAND:
			if (HIWORD(wParam) == BN_CLICKED)
			{
				switch (LOWORD(wParam))
				{
					case IDOK:
					case IDCANCEL:
					case IDCLOSE:
						aboutProc(hDlg, WM_CLOSE, 0, 0);
						return 1;
					case stConEmuUrl:
						ConEmuAbout::OnInfo_HomePage();
						return 1;
				}
			}
			break;

		case WM_NOTIFY:
		{
			LPNMHDR nmhdr = (LPNMHDR)lParam;
			if ((nmhdr->code == TCN_SELCHANGE) && (nmhdr->idFrom == tbAboutTabs))
			{
				int iPage = TabCtrl_GetCurSel(nmhdr->hwndFrom);
				if ((iPage >= 0) && (iPage < (int)countof(Pages)))
					SetDlgItemText(hDlg, tAboutText, Pages[iPage].Text);
			}
			break;
		}

		case WM_CLOSE:
			//if (ghWnd == NULL)
			gpConEmu->OnOurDialogClosed();
			EndDialog(hDlg, IDOK);
			//else
			//	DestroyWindow(hDlg);
			break;

		case WM_DESTROY:
			mh_AboutDlg = NULL;
			break;

		default:
			return FALSE;
	}

	return FALSE;
}