Пример #1
0
void SetUserFriendlyFont(HWND hConWnd)
{
    OSVERSIONINFO OSVer = {sizeof(OSVer)};
    GetVersionEx(&OSVer);

    // Соответствующие функции появились только в API Vista
    // Win2k & WinXP - доступны только хаки, что не подходит
    if (OSVer.dwMajorVersion >= 6)
    {
        HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        COORD crVisibleSize = {};
        CONSOLE_SCREEN_BUFFER_INFO csbi = {};
        if (GetConsoleScreenBufferInfo(hOutput, &csbi))
        {
            crVisibleSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
            crVisibleSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
        }

        if ((crVisibleSize.X <= 0) && (crVisibleSize.Y <= 0))
        {
            _ASSERTE((crVisibleSize.X > 0) && (crVisibleSize.Y > 0));
        }
        else
        {
            int curSizeY, curSizeX;
            wchar_t sFontName[LF_FACESIZE];

            if (apiGetConsoleFontSize(hOutput, curSizeY, curSizeX, sFontName) && curSizeY && curSizeX)
            {
                DEBUGTEST(COORD crLargest = MyGetLargestConsoleWindowSize(hOutput));

                HMONITOR hMon = MonitorFromWindow(hConWnd, MONITOR_DEFAULTTOPRIMARY);
                MONITORINFO mi = {sizeof(mi)};
                int nMaxX = 0, nMaxY = 0;
                if (GetMonitorInfo(hMon, &mi))
                {
                    nMaxX = mi.rcWork.right - mi.rcWork.left - 2*GetSystemMetrics(SM_CXSIZEFRAME) - GetSystemMetrics(SM_CYCAPTION);
                    nMaxY = mi.rcWork.bottom - mi.rcWork.top - 2*GetSystemMetrics(SM_CYSIZEFRAME);
                }

                if ((nMaxX > 0) && (nMaxY > 0))
                {
                    int nFontX = nMaxX  / crVisibleSize.X;
                    int nFontY = nMaxY / crVisibleSize.Y;
                    // Too large height?
                    if (nFontY > 28)
                    {
                        nFontX = 28 * nFontX / nFontY;
                        nFontY = 28;
                    }

                    // Evaluate default width for the font
                    int nEvalX = EvaluateDefaultFontWidth(nFontY, sFontName);
                    if (nEvalX > 0)
                    {
                        if ((nEvalX > nFontX) && (nFontX > 0))
                            nFontY = nFontX * nFontY / nEvalX;
                        else
                            nFontX = nEvalX;
                    }

                    // Look in the registry?
                    HKEY hk;
                    DWORD nRegSize = 0, nLen;
                    if (!RegOpenKeyEx(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hk))
                    {
                        if (RegQueryValueEx(hk, L"FontSize", NULL, NULL, (LPBYTE)&nRegSize, &(nLen=sizeof(nRegSize))) || nLen!=sizeof(nRegSize))
                            nRegSize = 0;
                        RegCloseKey(hk);
                    }
                    if (!nRegSize && !RegOpenKeyEx(HKEY_CURRENT_USER, L"Console\\%SystemRoot%_system32_cmd.exe", 0, KEY_READ, &hk))
                    {
                        if (RegQueryValueEx(hk, L"FontSize", NULL, NULL, (LPBYTE)&nRegSize, &(nLen=sizeof(nRegSize))) || nLen!=sizeof(nRegSize))
                            nRegSize = 0;
                        RegCloseKey(hk);
                    }
                    if ((HIWORD(nRegSize) > curSizeY) && (HIWORD(nRegSize) < nFontY)
                            && (LOWORD(nRegSize) > curSizeX) && (LOWORD(nRegSize) < nFontX))
                    {
                        nFontY = HIWORD(nRegSize);
                        nFontX = LOWORD(nRegSize);
                    }

                    if ((nFontX > curSizeX) || (nFontY > curSizeY))
                    {
                        apiSetConsoleFontSize(hOutput, nFontY, nFontX, sFontName);
                    }
                }
            }
        }
    }
}
Пример #2
0
// Vista+ only
BOOL apiFixFontSizeForBufferSize(HANDLE hOutput, COORD dwSize, char* pszUtfLog /*= NULL*/, int cchLogMax /*= 0*/)
{
	BOOL lbRetry = FALSE;
	CONSOLE_SCREEN_BUFFER_INFO csbi = {};

	if (pszUtfLog) *pszUtfLog = 0;

	if (dwSize.Y > 0 && dwSize.X > 0
		&& GetConsoleScreenBufferInfo(hOutput, &csbi))
	{
		COORD crLargest = MyGetLargestConsoleWindowSize(hOutput);
		int nMaxX = GetSystemMetrics(SM_CXFULLSCREEN);
		int nMaxY = GetSystemMetrics(SM_CYFULLSCREEN);

		#ifdef _DEBUG
		// Для отладки, смотрим какой размер получится по crLargest
		int nDbgFontX = crLargest.X ? (nMaxX / crLargest.X) : -1;
		int nDbgFontY = crLargest.Y ? (nMaxY / crLargest.Y) : -1;
		#endif
		
		int curSizeY, curSizeX, newSizeY, newSizeX, calcSizeY, calcSizeX;
		wchar_t sFontName[LF_FACESIZE];
		if (apiGetConsoleFontSize(hOutput, curSizeY, curSizeX, sFontName) && curSizeY && curSizeX)
		{
			// Увеличение
			if (crLargest.X && crLargest.Y && ((dwSize.X > crLargest.X) || (dwSize.Y > crLargest.Y)))
			{
				// Теперь прикинуть, какой размер шрифта нам нужен
				newSizeY = max(1,(nMaxY / (dwSize.Y+1)));
				newSizeX = max(1,(nMaxX / (dwSize.X+1)));
				if ((newSizeY < curSizeY) || (newSizeX < curSizeX))
				{
					calcSizeX = newSizeY * curSizeX / curSizeY;
					calcSizeY = newSizeX * curSizeY / curSizeX;
					if (calcSizeY < curSizeY)
						calcSizeX = min(calcSizeX,(calcSizeY * curSizeX / curSizeY));
					if (calcSizeX < curSizeX)
						calcSizeY = min(calcSizeY,(calcSizeX * curSizeY / curSizeX));

					newSizeY = max(1,min(calcSizeY,curSizeY));
					newSizeX = max(1,min(calcSizeX,curSizeX));
					lbRetry = TRUE;
				}
			}
			// Уменьшение
			else if ((dwSize.X <= (csbi.srWindow.Right - csbi.srWindow.Left))
				|| (dwSize.Y <= (csbi.srWindow.Bottom - csbi.srWindow.Top)))
			{
				int nMinY = GetSystemMetrics(SM_CYMIN) - GetSystemMetrics(SM_CYSIZEFRAME) - GetSystemMetrics(SM_CYCAPTION);
				int nMinX = GetSystemMetrics(SM_CXMIN) - 2*GetSystemMetrics(SM_CXSIZEFRAME);
				if ((nMinX > 0) && (nMinY > 0))
				{
					// Теперь прикинуть, какой размер шрифта нам нужен
					newSizeY = (nMinY / (dwSize.Y)) + 1;
					// Win8. На базовых настройках разбиение консоли дважды по Ctrl+Shift+O
					// дает ошибку - размер шрифта в третьей консоли оказывается недостаточным
					newSizeX = (nMinX / (dwSize.X)) + 2;
					if ((newSizeY > curSizeY) || (newSizeX > curSizeX))
					{
						calcSizeX = newSizeY * curSizeX / curSizeY;
						calcSizeY = newSizeX * curSizeY / curSizeX;
						if (calcSizeY > curSizeY)
							calcSizeX = max(calcSizeX,(calcSizeY * curSizeX / curSizeY));
						if (calcSizeX > curSizeX)
							calcSizeY = max(calcSizeY,(calcSizeX * curSizeY / curSizeX));

						newSizeY = max(calcSizeY,curSizeY);
						newSizeX = max(calcSizeX,curSizeX);
						lbRetry = TRUE;
					}
				}
			}

			if (lbRetry)
			{
				lbRetry = apiSetConsoleFontSize(hOutput, newSizeY, newSizeX, sFontName);
			}
		}
	}

	return lbRetry;
}
Пример #3
0
void SetUserFriendlyFont(HWND hConWnd, int newFontY = 0, int newFontX = 0)
{
	// Соответствующие функции появились только в API Vista
	// Win2k & WinXP - доступны только хаки, что не подходит
	_ASSERTE(_WIN32_WINNT_VISTA==0x600);
	OSVERSIONINFOEXW osvi = {sizeof(osvi), HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA)};
	DWORDLONG const dwlConditionMask = VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL);
	if (!VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask))
		return;

	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD crVisibleSize = {};
	CONSOLE_SCREEN_BUFFER_INFO csbi = {};
	if (GetConsoleScreenBufferInfo(hOutput, &csbi))
	{
		crVisibleSize.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
		crVisibleSize.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
	}

	if ((crVisibleSize.X <= 0) || (crVisibleSize.Y <= 0))
	{
		_ASSERTE((crVisibleSize.X > 0) && (crVisibleSize.Y > 0));
		return;
	}

	int curSizeY = 0, curSizeX = 0;
	wchar_t sFontName[LF_FACESIZE] = L"";

	if (apiGetConsoleFontSize(hOutput, curSizeY, curSizeX, sFontName) && curSizeY && curSizeX)
	{
		if (newFontY <= 0 || newFontX <= 0)
		{
			DEBUGTEST(COORD crLargest = MyGetLargestConsoleWindowSize(hOutput));

			HMONITOR hMon = MonitorFromWindow(hConWnd, MONITOR_DEFAULTTOPRIMARY);
			MONITORINFO mi = {sizeof(mi)};
			int nMaxX = 0, nMaxY = 0;
			if (GetMonitorInfo(hMon, &mi))
			{
				nMaxX = mi.rcWork.right - mi.rcWork.left - 2*GetSystemMetrics(SM_CXSIZEFRAME) - GetSystemMetrics(SM_CYCAPTION);
				nMaxY = mi.rcWork.bottom - mi.rcWork.top - 2*GetSystemMetrics(SM_CYSIZEFRAME);
			}

			if ((nMaxX > 0) && (nMaxY > 0))
			{
				int nFontX = nMaxX  / crVisibleSize.X;
				int nFontY = nMaxY / crVisibleSize.Y;
				// Too large height?
				if (nFontY > 28)
				{
					nFontX = 28 * nFontX / nFontY;
					nFontY = 28;
				}

				// Evaluate default width for the font
				int nEvalX = EvaluateDefaultFontWidth(nFontY, sFontName);
				if (nEvalX > 0)
				{
					if ((nEvalX > nFontX) && (nFontX > 0))
						nFontY = nFontX * nFontY / nEvalX;
					else
						nFontX = nEvalX;
				}

				// Look in the registry?
				HKEY hk;
				DWORD nRegSize = 0, nLen;
				if (!RegOpenKeyEx(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hk))
				{
					if (RegQueryValueEx(hk, L"FontSize", NULL, NULL, (LPBYTE)&nRegSize, &(nLen=sizeof(nRegSize))) || nLen!=sizeof(nRegSize))
						nRegSize = 0;
					RegCloseKey(hk);
				}
				if (!nRegSize && !RegOpenKeyEx(HKEY_CURRENT_USER, L"Console\\%SystemRoot%_system32_cmd.exe", 0, KEY_READ, &hk))
				{
					if (RegQueryValueEx(hk, L"FontSize", NULL, NULL, (LPBYTE)&nRegSize, &(nLen=sizeof(nRegSize))) || nLen!=sizeof(nRegSize))
						nRegSize = 0;
					RegCloseKey(hk);
				}
				if ((HIWORD(nRegSize) > curSizeY) && (HIWORD(nRegSize) < nFontY)
					&& (LOWORD(nRegSize) > curSizeX) && (LOWORD(nRegSize) < nFontX))
				{
					nFontY = HIWORD(nRegSize);
					nFontX = LOWORD(nRegSize);
				}

				if ((nFontX > curSizeX) || (nFontY > curSizeY))
				{
					newFontY = nFontY; newFontX = nFontX;
				}
			}
		}
	}

	if ((newFontY > 0) && (newFontX > 0))
	{
		if (!*sFontName)
			lstrcpyn(sFontName, L"Lucida Console", countof(sFontName));
		apiSetConsoleFontSize(hOutput, newFontY, newFontX, sFontName);
	}
}