Here is my first grid attempt.
James
'==============================================================================
#define unicode
#Include Once "windows.bi"
#Include Once "win/CommCtrl.bi"
#Include Once "Afx/CWindow.inc"
#Include Once "mCtrl/mCtrl.bi"
'------------------------------------------------------------------------------
#define CBCTLMSG HIWORD(wParam)
#define CBCTL LOWORD(wParam)
#define CBHNDL hWnd
#define CBHWND hWnd
#define CBLPARAM lParam
#define CBWPARAM wParam
#define CBMSG uMsg
'------------------------------------------------------------------------------
#define IDC_GRID 100
Using Afx.CWindowClass
Dim Shared As HWND ghwndGrid
Declare Function WinMain (Byval hInstance As HINSTANCE, _
Byval hPrevInstance As HINSTANCE, _
Byval szCmdLine As ZSTRING PTR, _
Byval nCmdShow As LONG) As LONG
END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)
'=======================================================================
Sub LoadGrid()
Dim hTable As MC_HTABLE
Dim tc As MC_TABLECELL
Dim As wstring *32 buffer
Dim As Long row,height
'/* Set size of the table to 8 columns and 16 rows. */
SendMessage(ghwndGrid, MC_GM_RESIZE, MAKEWPARAM(8, 16), 0)
tc.fMask = MC_TCMF_TEXT
tc.pszText = @buffer
For row = 0 To 15
buffer ="Row:" & Str$(row)
SendMessage ghwndGrid, MC_GM_SETCELL, MAKEWPARAM(MC_TABLE_HEADER, row), Cast(LPARAM, @tc)
Next
'/* Set a text of some cell */
tc.fMask = MC_TCMF_TEXT
tc.pszText = @buffer
buffer = "Hello World"
SendMessage ghwndGrid, MC_GM_SETCELL, MAKEWPARAM(1, 1), Cast(LPARAM, @tc)
'/* We can also get the data model of the grid control and manipulate it directly. */
hTable = Cast(MC_HTABLE,SendMessage(ghwndGrid, MC_GM_GETTABLE, 0, 0))
tc.fMask = MC_TCMF_TEXT OR MC_TCMF_FLAGS
buffer = "top left"
tc.dwFlags = MC_TCF_ALIGNLEFT OR MC_TCF_ALIGNTOP
mcTable_SetCell(hTable, 4, 10, @tc)
buffer = "top center"
tc.dwFlags = MC_TCF_ALIGNCENTER OR MC_TCF_ALIGNTOP
mcTable_SetCell(hTable, 5, 10, @tc)
buffer = "top right"
tc.dwFlags = MC_TCF_ALIGNRIGHT OR MC_TCF_ALIGNTOP
mcTable_SetCell(hTable, 6, 10, @tc)
buffer = "middle left"
tc.dwFlags = MC_TCF_ALIGNLEFT OR MC_TCF_ALIGNVCENTER
mcTable_SetCell(hTable, 4, 11, @tc)
buffer = "middle center"
tc.dwFlags = MC_TCF_ALIGNCENTER OR MC_TCF_ALIGNVCENTER
mcTable_SetCell(hTable, 5, 11, @tc)
buffer = "middle right"
tc.dwFlags = MC_TCF_ALIGNRIGHT OR MC_TCF_ALIGNVCENTER
mcTable_SetCell(hTable, 6, 11, @tc)
buffer = "bottom left"
tc.dwFlags = MC_TCF_ALIGNLEFT OR MC_TCF_ALIGNBOTTOM
mcTable_SetCell(hTable, 4, 12, @tc)
buffer = "bottom center"
tc.dwFlags = MC_TCF_ALIGNCENTER OR MC_TCF_ALIGNBOTTOM
mcTable_SetCell(hTable, 5, 12, @tc)
buffer = "bottom right"
tc.dwFlags = MC_TCF_ALIGNRIGHT OR MC_TCF_ALIGNBOTTOM
mcTable_SetCell(hTable, 6, 12, @tc)
'/* Set heights of few rows to a different value. */
height = LOWORD(SendMessage(ghwndGrid, MC_GM_GETROWHEIGHT, 10, 0))
height *= 2
SendMessage(ghwndGrid, MC_GM_SETROWHEIGHT, 10, MAKEWPARAM(height, 0))
SendMessage(ghwndGrid, MC_GM_SETROWHEIGHT, 11, MAKEWPARAM(height, 0))
SendMessage(ghwndGrid, MC_GM_SETROWHEIGHT, 12, MAKEWPARAM(height, 0))
End Sub
'=======================================================================
Function WndProc (Byval hWnd As HWND, Byval uMsg As UINT, Byval wParam As WPARAM, Byval lParam As LPARAM) As LRESULT
Select Case uMsg
Case WM_CREATE
Case WM_NOTIFY
Dim As NMHDR Ptr hdr = Cast(NMHDR Ptr,lParam)
If hdr->idFrom = IDC_GRID AND hdr->code = MC_GN_ENDLABELEDIT Then
'/* Accept the new text when user edits a cell label. Application
' * should implement this notification whenever it created the
' * grid control with the style MC_GS_EDITLABELS. */
Return TRUE
EndIf
Case WM_SIZE
'/* Resize the grid control so it takes all space of the top
' * level window */
If CBWPARAM = SIZE_RESTORED OR CBWPARAM = SIZE_MAXIMIZED Then
SetWindowPos(ghwndGrid, NULL, 5, 5, LOWORD(lParam)-10, HIWORD(lParam)-10, SWP_NOZORDER)
EndIf
Case WM_SETFONT
Dim As MC_GGEOMETRY geom
SendMessage(ghwndGrid, WM_SETFONT, wParam, lParam)
'/* Reset grid's geometry to defaults according to the font. */
SendMessage(ghwndGrid, MC_GM_SETGEOMETRY, 0, 0)
'/* Make it to use a bit more space. */
geom.fMask = MC_GGF_ROWHEADERWIDTH OR MC_GGF_DEFCOLUMNWIDTH
SendMessage ghwndGrid, MC_GM_GETGEOMETRY, 0, Cast(LPARAM,@geom)
geom.wRowHeaderWidth = 50
geom.wDefColumnWidth += geom.wDefColumnWidth / 2
SendMessage ghwndGrid, MC_GM_SETGEOMETRY, 0, Cast(LPARAM,@geom)
Return FALSE
Case WM_SETFOCUS
SetFocus ghwndGrid
Return FALSE
Case WM_DESTROY
PostQuitMessage(0)
Exit Function
End Select
Function = DefWindowProc(hWnd, uMsg, wParam, lParam)
End Function
'==============================================================================
Function WinMain (Byval hInstance As HINSTANCE, _
Byval hPrevInstance As HINSTANCE, _
Byval szCmdLine As ZSTRING PTR, _
Byval nCmdShow As LONG) As LONG
Dim As Boolean retval
If mcGrid_Initialize() = FALSE Then
AfxMsg("NO")
Exit Function
EndIf
' // Set process DPI aware
AfxSetProcessDPIAware
Dim As CWindow pWindow
pWindow.Create(NULL, "Edit controls", @WndProc)
pWindow.SetClientSize 600, 440
pWindow.AddControl(MC_WC_GRID,,IDC_GRID,"",0,0,0,0, _
WS_CHILD OR WS_VISIBLE OR WS_TABSTOP OR _
MC_GS_COLUMNHEADERALPHABETIC OR MC_GS_ROWHEADERNORMAL OR _
MC_GS_RESIZABLECOLUMNS OR MC_GS_RESIZABLEROWS OR _
MC_GS_FOCUSEDCELL OR MC_GS_COMPLEXSEL OR MC_GS_SHOWSELALWAYS OR _
MC_GS_EDITLABELS,WS_EX_CLIENTEDGE)
pWindow.Center
ghwndGrid = pWindow.ControlHandle(IDC_GRID)
LoadGrid()
Function = pWindow.DoEvents(nCmdShow)
mcGrid_Terminate()
End Function
Yet another control that is not DPI aware.
The programmer should implement a message to pass the DPI and do scaling.
e.g. SendMessage hCtrl, <message>, rxRatio, ryRatio
Hi Jose,
I am curious as to how my grid looks on your system. It has been a while since I worked on the source code because I have been focusing on your CWindow and WinFBE.
The demo attached may look a little strange because I was playing with different cell coloring options.
Does it display okay on your system?
Edit: Attachment removed. See later post with fixed exe attachment.
Yes, but because the test is not DPI aware and runs virtualized (=fuzzy fonts).
But if I disable virtualization then... (see capture).
IMO the control should not calculate the scaling ratios, but allow the user to pass them. If the user does not do it, then calculate the ratios according the DPI, but always give the user the opportunity to set the values.
CWindow calculates the scaling, but allows you to use different scaling ratios just by setting the DPI property before calling the Create method, e.g. pWindow.DPI = 96, disables scaling; any other value, zooms in or out.
Thanks Jose, I thought that I was correctly building scaling into the control (I must have screwed up there somewhere along the way). I will check the source code again and build it along the lines of your thinking (allow the user to pass the scaling ratios). I will build the sample program using CWindow and then call the grid control using CWindow determined scaling ratios.
If you aren't using a high dpi, you can simulate it, e.g.
DIM pWindow AS CWindow
pWindow.DPI = 192
Jose,
The mCtrl author was very receptive to issues:
http://forum.pellesc.de/index.php?topic=6966.0
Maybe you can post at his git site or send him an email?
https://github.com/mity/mctrl/issues
James
Don't know yet if I'm going to use it or not. I expect to have the same kind of problems with the other controls.
I don't know why they do so much work to write the controls and don't pay any attention to the High DPI issue.
Lots of applications with dialogs that are bigger than the height of my monitor (try to click a button that it is not visible), blurriness, artifacts, clipped text, drag and drop problems between a virtualized application and a DPI aware one), etc.
What are you doing, guys? Do you have the monitor under your nose? I have my monitor at 1.5 meters of distance and I can't read anything if I use 96 DPI (I'm using 192 DPI).
What will happen when 4k monitors will become the norm?
(https://www.planetsquires.com/protect/forum/proxy.php?request=http%3A%2F%2Fep.yimg.com%2Fay%2Fsightmart-eye-care-products%2F15-inch-laptop-computer-2x-magnifier-6.gif&hash=8241a266d6548c97711b53d0c414657dae632d94)
Jose,
1.5 meters?? Wow thats almost 5 feet isn't it? You must have extremely long arms :).
My desktop monitor is ~ 2 feet and my laptops are ~ 1.5 feet. Text is small but lots of real-estate even though I do need reading glasses .
James
I don't touch the screen. I only use the mouse and the keyboard.
If I put it at that distance and use a high dpi value, I can read it without glasses. If I put it close to mi nose, I need to use reading glasses. So the first option is more comfortable to me.
Jose,
You are correct that add-on controls SHOULD be dpi aware even though most apps are not.
I sent the author an email with your attached image.
James
Quote from: Jose Roca on June 14, 2016, 09:55:34 PM
IMO the control should not calculate the scaling ratios, but allow the user to pass them. If the user does not do it, then calculate the ratios according the DPI, but always give the user the opportunity to set the values.
CWindow calculates the scaling, but allows you to use different scaling ratios just by setting the DPI property before calling the Create method, e.g. pWindow.DPI = 96, disables scaling; any other value, zooms in or out.
Thanks Jose - I have changed my code to allow the user to pass the scaling ratios to the control, I have also changed the code so that font handles are passed to the control rather than have the control create them. The user is now responsible for creating the font, passing it to the control, and then destroying it when no longer needed. This should make it a lot easier to use scaled CWindow fonts with the grid. I tried the changes on my computer with the DPI changed and it looks much better than before.
Edit: Updated. Forgot to take out my 96 DPI testing line!
Still some work to do.
After understanding DPI, the next step is understanding DIPs (device-independent pixels).
A DIP is defined as 1/96th of a logical inch.
DPI setting DIP size
96 1 pixel
120 1.25 pixels
144 1.5 pixels
192 2 pixels
If we pass the values to functions or methods that do not do automatic scaling, we have to multiply the pixels by the scaling ratio, because a pixel is a pixel only at 96 DPI.
Quote from: James Fuller on June 15, 2016, 11:14:37 AM
Jose,
You are correct that add-on controls SHOULD be dpi aware even though most apps are not.
I sent the author an email with your attached image.
James
Guess you don't have any news. A pity, because some controls could be useful.
Jose,
He said he would look into it but .... no word yet, email or news on his site
James
Jose,
I just noticed there was a new release in October.
James
Thanks, James, but controls that are not DPI aware are'nt usable by me.