Caveats: Instead of RGB we have to use BGR, with the colors reversed. Some messages, like NM_CUSTOMDRAW, are defined as negative numbers (I miss PB's sufixes such ???), so I have needed to use CASE CULNG(NM_CUSTOMDRAW) instead of CASE NM_CUSTOMDRAW (*).
Adding the columns and items of the listview without wrappers is a pain.
' ########################################################################################
' Microsoft Windows
' File: CW_LV_CustomDraw_HDPI.fbtpl
' Contents: Template - CWindow with a custom draw ListView (High DPI)
' Compiler: Free Basic
' Copyright (c) 2015 Jose Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#define unicode
#INCLUDE ONCE "windows.bi"
#INCLUDE ONCE "Afx/CWindow.inc"
#INCLUDE ONCE "Afx/AfxWin.inc"
#define IDC_LISTVIEW 1001
USING Afx.CWindowClass
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, COMMAND(), SW_NORMAL)
' ========================================================================================
' Window procedure
' ================================================================e========================
FUNCTION WndProc (BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
DIM pNmh AS NMHDR PTR ' // Pointer to a NMHDR structure
DIM pLvNm AS NMLISTVIEW PTR ' // Pointer to a NMLISTVIEW structure
DIM pLvCd AS NMLVCUSTOMDRAW PTR ' // Pointer to a NMLVCUSTOMDRAW structure
FUNCTION = 0
SELECT CASE AS CONST uMsg
CASE WM_CREATE
EXIT FUNCTION
CASE WM_COMMAND
SELECT CASE LOWORD(wParam)
' // If the user press the ESC key...
CASE IDCANCEL
' // ...send a message to close the application
IF HIWORD(wParam) = BN_CLICKED THEN
SendMessageW hwnd, WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE WM_SIZE
' // Resize the ListView control and its header
IF wParam <> SIZE_MINIMIZED THEN
DIM hListView AS HWND, pWindow AS CWindow PTR
pWindow = CAST(CWindow PTR, GetPropW(hwnd, "CWINDOWPTR"))
hListView = GetDlgItem(hwnd, IDC_LISTVIEW)
pWindow->MoveWindow hListView, 5, 5, pWindow->ClientWidth - 10, pWindow->ClientHeight - 10, TRUE
END IF
CASE WM_NOTIFY
' // Processs notify messages sent by the list view control
pNmh = CAST(NMHDR PTR, lParam)
SELECT CASE pNmh->idFrom
CASE IDC_LISTVIEW
pLvNm = CAST(NMLISTVIEW PTR, lParam)
SELECT CASE pLvNm->hdr.code
CASE CULNG(NM_CUSTOMDRAW) ' CULNG needed because NM_CUSTOMDRAW is negative
pLvCd = CAST(NMLVCUSTOMDRAW PTR, lParam)
SELECT CASE pLvCd->nmcd.dwDrawStage
CASE CDDS_PREPAINT, CDDS_ITEMPREPAINT
' // Tell the list view to send the %CDDS_ITEMPREPAINT OR %CDDS_SUBITEM notification message
FUNCTION = CDRF_NOTIFYSUBITEMDRAW
EXIT FUNCTION
CASE CDDS_ITEMPREPAINT OR CDDS_SUBITEM
IF pLvCd->iSubItem = 0 THEN
' // Paint the first column with a gray background
pLvCd->clrTextBk = BGR(&HD3, &HD3, &HD3)
pLvCd->clrText = BGR(&H00, &H00, &H00)
ELSE
IF (pLvCd->nmcd.dwItemSpec MOD 2) = 0 THEN
' // Paint the columns of odd rows with a white background
pLvCd->clrTextBk = BGR(&HFF, &HFF, &HFF)
pLvCd->clrText = BGR(&H00, &H00, &H00)
ELSE
' // Paint the columns of even rows with a pale turquoise background
pLvCd->clrTextBk = BGR(&HAF, &HEE, &HEE)
pLvCd->clrText = BGR(&H00, &H00, &H00)
END IF
END IF
' // Tell the list view to draw itself
FUNCTION = CDRF_DODEFAULT
EXIT FUNCTION
END SELECT
END SELECT
END SELECT
CASE WM_DESTROY
' // End the application
PostQuitMessage(0)
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to DefWindowProc
FUNCTION = DefWindowProcW(hWnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL szCmdLine AS ZSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI aware
AfxSetProcessDPIAware
DIM pWindow AS CWindow
pWindow.Create(NULL, "Custom Draw ListView (High DPI)", @WndProc)
pWindow.ClassStyle = CS_DBLCLKS ' // Change the window style to avoid flicker
pWindow.SetClientSize(565, 320)
pWindow.Center
' // Adds a listview
DIM hListView AS HWND
hListView = pWindow.AddControl("ListView", pWindow.hWindow, IDC_LISTVIEW, "")
' // Add some extended styles
DIM dwExStyle AS DWORD
dwExStyle = ListView_GetExtendedListViewStyle(hListView)
dwExStyle = dwExStyle OR LVS_EX_FULLROWSELECT OR LVS_EX_GRIDLINES
ListView_SetExtendedListViewStyle(hListView, dwExStyle)
' // Add the header's column names
DIM i AS LONG, lvc AS LVCOLUMNW, wszText AS WSTRING * 260
lvc.mask = LVCF_FMT OR LVCF_WIDTH OR LVCF_TEXT OR LVCF_SUBITEM
FOR i = 0 TO 4
wszText = "Column " & STR(i)
lvc.pszText = @wszText
lvc.cx = pWindow.ScaleX(110)
lvc.iSubItem = i
SendMessageW(hListView, LVM_INSERTCOLUMNW, i, CAST(LPARAM, @lvc))
NEXT
' // Populate the ListView with some data
DIM x AS LONG
DIM lvi AS LVITEMW
lvi.mask = LVIF_TEXT
FOR i = 0 to 29
lvi.iItem = i
lvi.iSubItem = 0
wszText = "Column 0 Row" + STR(i)
lvi.pszText = @wszText
ListView_InsertItem(hListView, @lvi)
FOR x = 1 TO 4
lvi.iSubItem = x
wszText = "Column " & STR(x) & " Row" + STR(i)
lvi.pszText = @wszText
SendMessageW hListView, LVM_SETITEMTEXTW, i, CAST(LPARAM, @lvi)
NEXT
NEXT
' // Select the fist item
ListView_SetItemState(hListView, 0, LVIS_FOCUSED OR LVIS_SELECTED, &H000F)
' // Set the focus in the ListView
SetFocus hListView
FUNCTION = pWindow.DoEvents(nCmdShow)
END FUNCTION
' ========================================================================================
(*) There are several negative notification messages that need to be converted to ULONG (DWORD).
#define NM_OUTOFMEMORY (NM_FIRST - 1)
#define NM_CLICK (NM_FIRST - 2)
#define NM_DBLCLK (NM_FIRST - 3)
#define NM_RETURN (NM_FIRST - 4)
#define NM_RCLICK (NM_FIRST - 5)
#define NM_RDBLCLK (NM_FIRST - 6)
#define NM_SETFOCUS (NM_FIRST - 7)
#define NM_KILLFOCUS (NM_FIRST - 8)
#define NM_CUSTOMDRAW (NM_FIRST - 12)
#define NM_HOVER (NM_FIRST - 13)
#define NM_NCHITTEST (NM_FIRST - 14)
#define NM_KEYDOWN (NM_FIRST - 15)
#define NM_RELEASEDCAPTURE (NM_FIRST - 16)
#define NM_SETCURSOR (NM_FIRST - 17)
#define NM_CHAR (NM_FIRST - 18)
#define NM_TOOLTIPSCREATED (NM_FIRST - 19)
#define NM_LDOWN (NM_FIRST - 20)
#define NM_RDOWN (NM_FIRST - 21)
#define NM_THEMECHANGED (NM_FIRST - 22)
#if _WIN32_WINNT = &h0602
#define NM_FONTCHANGED (NM_FIRST - 23)
#define NM_CUSTOMTEXT (NM_FIRST - 24)
#define NM_TVSTATEIMAGECHANGING (NM_FIRST - 24)
#endif
I am on my way out for a few hours but your post triggered a memory I had of a post I made on the FB forums a few months. I wonder if your negative equates issue is the same as this one: http://www.freebasic.net/forum/viewtopic.php?f=6&t=23212#p204479 I will lookk at it more when I get home from.... Universal Studios Florida theme park!!! :) :) :)
Yes, the same issue. The negative numbers need to be converted to ULONG.
http://www.freebasic.net/forum/viewtopic.php?f=6&t=23901