Skip to content

Commit

Permalink
flog: System DPI awareness.
Browse files Browse the repository at this point in the history
  • Loading branch information
wishstudio committed Feb 21, 2016
1 parent f36b86f commit 3a7d9d2
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 26 deletions.
2 changes: 2 additions & 0 deletions flog/flog.vcxproj
Expand Up @@ -125,6 +125,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\DPIAware.cpp" />
<ClCompile Include="src\LogServer.cpp" />
<ClCompile Include="src\LogViewer.cpp" />
<ClCompile Include="src\Main.cpp" />
Expand All @@ -137,6 +138,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\DPIAware.h" />
<ClInclude Include="src\LogServer.h" />
<ClInclude Include="src\LogViewer.h" />
<ClInclude Include="src\MainWindow.h" />
Expand Down
2 changes: 2 additions & 0 deletions flog/flog.vcxproj.filters
Expand Up @@ -6,13 +6,15 @@
<ClCompile Include="src\pch.cpp" />
<ClCompile Include="src\LogServer.cpp" />
<ClCompile Include="src\LogViewer.cpp" />
<ClCompile Include="src\DPIAware.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\MainWindow.h" />
<ClInclude Include="src\Resource.h" />
<ClInclude Include="src\pch.h" />
<ClInclude Include="src\LogServer.h" />
<ClInclude Include="src\LogViewer.h" />
<ClInclude Include="src\DPIAware.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="src\Resource.rc" />
Expand Down
40 changes: 40 additions & 0 deletions flog/src/DPIAware.cpp
@@ -0,0 +1,40 @@
/*
* This file is part of Foreign Linux.
*
* Copyright (C) 2015, 2016 Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "pch.h"

#include "DPIAware.h"

void DPIAware::Init(HWND hWnd)
{
HDC hdc = GetDC(hWnd);
m_dpix = GetDeviceCaps(hdc, LOGPIXELSX);
m_dpiy = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(hWnd, hdc);
}

int DPIAware::GetPhysicalX(int logicalX)
{
return MulDiv(logicalX, m_dpix, 96);
}

int DPIAware::GetPhysicalY(int logicalY)
{
return MulDiv(logicalY, m_dpiy, 96);
}
33 changes: 33 additions & 0 deletions flog/src/DPIAware.h
@@ -0,0 +1,33 @@
/*
* This file is part of Foreign Linux.
*
* Copyright (C) 2015, 2016 Xiangyan Sun <wishstudio@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#define GetPhysicalXY(X, Y) GetPhysicalX(X), GetPhysicalY(Y)

class DPIAware
{
protected:
void Init(HWND hWnd);
int GetPhysicalX(int logicalX);
int GetPhysicalY(int logicalY);

private:
int m_dpix, m_dpiy;
};
38 changes: 20 additions & 18 deletions flog/src/LogViewer.cpp
Expand Up @@ -27,7 +27,9 @@ HWND LogViewer::Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName)
HWND hWnd = CWindowImpl<LogViewer>::Create(hWndParent, rect, szWindowName,
WS_CHILD | WS_VISIBLE | WS_VSCROLL,
WS_EX_CLIENTEDGE);
m_font.CreateFont(FONT_SIZE, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, _T("Consolas"));
DPIAware::Init(hWnd);
m_font.CreateFont(GetPhysicalY(FONT_SIZE), 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, _T("Consolas"));
m_timerShot = false;
m_mouseDown = false;
m_selStart = std::make_pair(0, 0);
Expand All @@ -42,7 +44,7 @@ void LogViewer::DoPaint(CDCHandle dc)
POINT offset;
GetScrollOffset(offset);

RECT clientRect;
RECT clientRect; /* In physical coordinates */
GetClientRect(&clientRect);
/* Erase background */
dc.FillRect(&clientRect, COLOR_WINDOW);
Expand All @@ -52,14 +54,14 @@ void LogViewer::DoPaint(CDCHandle dc)
selEnd = max(m_selStart, m_selEnd);
dc.SelectFont(m_font);
dc.SetBkMode(TRANSPARENT);
for (int i = offset.y / FONT_SIZE; i < (int)m_lines.size(); i++)
for (int i = offset.y / GetPhysicalY(FONT_SIZE); i < (int)m_lines.size(); i++)
{
int y = clientRect.top + i * FONT_SIZE - offset.y;
int y = clientRect.top + GetPhysicalY(i * FONT_SIZE) - offset.y;
if (y > clientRect.bottom)
break;
RECT rect = clientRect;
RECT rect = clientRect; /* In physical coordinates */
rect.top = y;
rect.bottom = y + FONT_SIZE;
rect.bottom = y + GetPhysicalY(FONT_SIZE);
if (m_types[i] == LOG_DEBUG)
dc.FillSolidRect(&rect, RGB(0xE0, 0xF0, 0xFF));
if (m_types[i] == LOG_WARNING)
Expand All @@ -85,15 +87,15 @@ void LogViewer::DoPaint(CDCHandle dc)
else
end = m_lines[i].size();
int x = 0;
SIZE size;
SIZE size; /* In physical coordinates */
/* Draw text before selection */
GetTextExtentPoint32W(dc, m_lines[i].c_str(), start, &size);
dc.ExtTextOutW(x, y, 0, NULL, m_lines[i].c_str(), start, 0);
x += size.cx;
/* Draw selection */
dc.SetTextColor(RGB(0xFF, 0xFF, 0xFF));
GetTextExtentPoint32W(dc, m_lines[i].c_str() + start, end - start, &size);
dc.FillSolidRect(x, y, size.cx, FONT_SIZE, RGB(0x00, 0xAA, 0xFF));
dc.FillSolidRect(x, y, size.cx, GetPhysicalY(FONT_SIZE), RGB(0x00, 0xAA, 0xFF));
dc.ExtTextOutW(x, y, 0, NULL, m_lines[i].c_str() + start, end - start, 0);
x += size.cx;
/* Draw text after selection */
Expand All @@ -110,7 +112,7 @@ void LogViewer::OnTimer(UINT_PTR id)
bool atBottom = false;
if (offset.y >= m_sizeAll.cy - m_sizeClient.cy - 1)
atBottom = true;
SetScrollSize(1, m_lines.size() * FONT_SIZE, TRUE, FALSE);
SetScrollSize(1, m_lines.size() * GetPhysicalY(FONT_SIZE), TRUE, FALSE);
SetScrollLine(0, FONT_SIZE);
if (atBottom)
{
Expand All @@ -129,7 +131,7 @@ void LogViewer::OnTimer(UINT_PTR id)

void LogViewer::OnSetFocus(CWindow wndOld)
{
CreateSolidCaret(1, FONT_SIZE);
CreateSolidCaret(1, GetPhysicalY(FONT_SIZE));
UpdateCaret(false);
ShowCaret();
}
Expand Down Expand Up @@ -192,7 +194,7 @@ void LogViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CPoint point = TranslateCharPosToClientPoint(m_selEnd);
m_savedX = max(m_savedX, point.x);
int y = (m_selEnd.first - 1) * FONT_SIZE;
int y = (m_selEnd.first - 1) * GetPhysicalY(FONT_SIZE);
m_selEnd = TranslateClientPointToCharPos(CPoint(m_savedX, y));
}
if (!shift)
Expand All @@ -204,7 +206,7 @@ void LogViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CPoint point = TranslateCharPosToClientPoint(m_selEnd);
m_savedX = max(m_savedX, point.x);
int y = (m_selEnd.first + 1) * FONT_SIZE;
int y = (m_selEnd.first + 1) * GetPhysicalY(FONT_SIZE);
m_selEnd = TranslateClientPointToCharPos(CPoint(m_savedX, y));
}
if (!shift)
Expand All @@ -216,7 +218,7 @@ void LogViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CPoint point = TranslateCharPosToClientPoint(m_selEnd);
m_savedX = max(m_savedX, point.x);
int y = max(0, m_selEnd.first - pageSize) * FONT_SIZE;
int y = max(0, m_selEnd.first - pageSize) * GetPhysicalY(FONT_SIZE);
m_selEnd = TranslateClientPointToCharPos(CPoint(m_savedX, y));
}
if (!shift)
Expand All @@ -228,7 +230,7 @@ void LogViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CPoint point = TranslateCharPosToClientPoint(m_selEnd);
m_savedX = max(m_savedX, point.x);
int y = min((int)m_lines.size() - 1, m_selEnd.first + pageSize) * FONT_SIZE;
int y = min((int)m_lines.size() - 1, m_selEnd.first + pageSize) * GetPhysicalY(FONT_SIZE);
m_selEnd = TranslateClientPointToCharPos(CPoint(m_savedX, y));
}
if (!shift)
Expand All @@ -249,7 +251,7 @@ void LogViewer::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
break;

case VK_RIGHT:
if (m_selEnd.second == (int)m_lines[m_selEnd.first].size() && m_selEnd.first < (int)m_lines.size())
if (m_selEnd.second == (int)m_lines[m_selEnd.first].size() && m_selEnd.first + 1 < (int)m_lines.size())
{
m_selEnd.first++;
m_selEnd.second = 0;
Expand Down Expand Up @@ -323,7 +325,7 @@ std::pair<int, int> LogViewer::TranslateMousePoint(CPoint mousePoint)

std::pair<int, int> LogViewer::TranslateClientPointToCharPos(CPoint clientPoint)
{
int y = clientPoint.y / FONT_SIZE;
int y = clientPoint.y / GetPhysicalY(FONT_SIZE);
if (y < 0)
y = 0;
if (y >= (int)m_lines.size())
Expand Down Expand Up @@ -371,12 +373,12 @@ CPoint LogViewer::TranslateCharPosToClientPoint(std::pair<int, int> pos)
SIZE size;
GetTextExtentPoint32W(dc, m_lines[pos.first].c_str(), pos.second, &size);
ReleaseDC(dc);
return CPoint(size.cx, pos.first * FONT_SIZE);
return CPoint(size.cx, pos.first * GetPhysicalY(FONT_SIZE));
}

void LogViewer::UpdateCaret(bool scrollToCaret)
{
int y = m_selEnd.first * FONT_SIZE;
int y = m_selEnd.first * GetPhysicalY(FONT_SIZE);
int x = 0;
if (!m_lines.empty())
{
Expand Down
3 changes: 2 additions & 1 deletion flog/src/LogViewer.h
Expand Up @@ -19,9 +19,10 @@

#pragma once

#include "DPIAware.h"
#include "LogServer.h"

class LogViewer: public CWindowImpl<LogViewer>, public CScrollImpl<LogViewer>, public CDoubleBufferImpl<LogViewer>
class LogViewer: public CWindowImpl<LogViewer>, public CScrollImpl<LogViewer>, public CDoubleBufferImpl<LogViewer>, public DPIAware
{
public:
static ATL::CWndClassInfo& GetWndClassInfo()
Expand Down
3 changes: 2 additions & 1 deletion flog/src/Main.cpp
Expand Up @@ -29,10 +29,11 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
CAppModule Module;
Module.Init(NULL, hInstance);

SetProcessDPIAware();

MainWindow mainWindow;
if (mainWindow.Create(NULL, CWindow::rcDefault, L"Foreign Linux Logger"))
{
mainWindow.ResizeClient(1280, 720);
mainWindow.CenterWindow();
mainWindow.ShowWindow(nCmdShow);
mainWindow.UpdateWindow();
Expand Down
9 changes: 5 additions & 4 deletions flog/src/MainWindow.cpp
Expand Up @@ -22,13 +22,13 @@

LRESULT MainWindow::OnCreate(LPCREATESTRUCT cs)
{
DPIAware::Init(*this);

m_processTree.Create(*this, rcDefault, NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS,
WS_EX_CLIENTEDGE);

m_splitter.Create(*this, rcDefault, NULL, WS_CHILD | WS_VISIBLE);
m_logViewerFont.CreateFontW(18, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, FF_DONTCARE, L"Consolas");
InitLogViewer(m_defaultLogViewer);
m_defaultLogViewer.SetWindowTextW(L"No Foreign Linux client connected.");

Expand All @@ -37,11 +37,13 @@ LRESULT MainWindow::OnCreate(LPCREATESTRUCT cs)
m_hWndClient = m_splitter;
UpdateLayout();

m_splitter.SetSplitterPos(240);
m_splitter.SetSplitterPos(GetPhysicalX(240));
m_splitter.SetSplitterExtendedStyle(0);
m_splitter.m_bFullDrag = FALSE;

m_logServer.Start(*this);

ResizeClient(GetPhysicalX(1280), GetPhysicalY(720));
return 0;
}

Expand Down Expand Up @@ -166,7 +168,6 @@ void MainWindow::ProcessClientLog(Client *client, LogPacket *packet)
void MainWindow::InitLogViewer(LogViewer &logViewer)
{
logViewer.Create(m_splitter, rcDefault);
logViewer.SetFont(m_logViewerFont);
}

void MainWindow::SetCurrentLogViewer(LogViewer &logViewer)
Expand Down
4 changes: 2 additions & 2 deletions flog/src/MainWindow.h
Expand Up @@ -19,10 +19,11 @@

#pragma once

#include "DPIAware.h"
#include "LogServer.h"
#include "LogViewer.h"

class MainWindow: public CFrameWindowImpl<MainWindow>
class MainWindow: public CFrameWindowImpl<MainWindow>, public DPIAware
{
public:
BEGIN_MSG_MAP(MainWindow)
Expand Down Expand Up @@ -58,7 +59,6 @@ class MainWindow: public CFrameWindowImpl<MainWindow>
LogServer m_logServer;
CSplitterWindow m_splitter;
CTreeViewCtrl m_processTree;
CFont m_logViewerFont;
LogViewer m_defaultLogViewer;
std::vector<std::vector<std::unique_ptr<Client>>> m_clients;
};

0 comments on commit 3a7d9d2

Please sign in to comment.