Created
May 12, 2015 04:58
-
-
Save yonran/706f84f0d489a47926cd to your computer and use it in GitHub Desktop.
Example code for question http://stackoverflow.com/questions/30182109/how-to-set-focus-on-a-list-view-item
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! cl.exe /Tp listviwe_setselectionmark.cpp User32.lib ComCtl32.lib Ole32.lib | |
#define STRICT | |
#define UNICODE | |
#define _UNICODE | |
#include <windows.h> | |
#include <windowsx.h> | |
#include <ole2.h> | |
#include <commctrl.h> | |
#include <shlwapi.h> | |
#include <shlobj.h> | |
#include <shellapi.h> | |
#include <stdlib.h> // rand | |
HINSTANCE g_hinst; | |
const WORD IDM_SELECTRANDOM = 1; | |
class Window | |
{ | |
public: | |
HWND GetHWND() { return m_hwnd; } | |
protected: | |
virtual LRESULT HandleMessage( | |
UINT uMsg, WPARAM wParam, LPARAM lParam); | |
virtual void PaintContent(PAINTSTRUCT *pps) { } | |
virtual LPCTSTR ClassName() = 0; | |
virtual BOOL WinRegisterClass(WNDCLASS *pwc) | |
{ return RegisterClass(pwc); } | |
virtual ~Window() { } | |
HWND WinCreateWindow(DWORD dwExStyle, LPCTSTR pszName, | |
DWORD dwStyle, int x, int y, int cx, int cy, | |
HWND hwndParent, HMENU hmenu) | |
{ | |
Register(); | |
return CreateWindowEx(dwExStyle, ClassName(), pszName, dwStyle, | |
x, y, cx, cy, hwndParent, hmenu, g_hinst, this); | |
} | |
private: | |
void Register(); | |
void OnPaint(); | |
void OnPrintClient(HDC hdc); | |
static LRESULT CALLBACK s_WndProc(HWND hwnd, | |
UINT uMsg, WPARAM wParam, LPARAM lParam); | |
protected: | |
HWND m_hwnd; | |
}; | |
void Window::Register() | |
{ | |
WNDCLASS wc; | |
wc.style = 0; | |
wc.lpfnWndProc = Window::s_WndProc; | |
wc.cbClsExtra = 0; | |
wc.cbWndExtra = 0; | |
wc.hInstance = g_hinst; | |
wc.hIcon = NULL; | |
wc.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); | |
wc.lpszMenuName = NULL; | |
wc.lpszClassName = ClassName(); | |
WinRegisterClass(&wc); | |
} | |
LRESULT CALLBACK Window::s_WndProc( | |
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
Window *self; | |
if (uMsg == WM_NCCREATE) { | |
LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); | |
self = reinterpret_cast<Window *>(lpcs->lpCreateParams); | |
self->m_hwnd = hwnd; | |
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(self)); | |
} else { | |
self = reinterpret_cast<Window *>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); | |
} | |
if (self) { | |
return self->HandleMessage(uMsg, wParam, lParam); | |
} else { | |
return DefWindowProc(hwnd, uMsg, wParam, lParam); | |
} | |
} | |
LRESULT Window::HandleMessage( | |
UINT uMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
LRESULT lres; | |
switch (uMsg) { | |
case WM_NCDESTROY: | |
lres = DefWindowProc(m_hwnd, uMsg, wParam, lParam); | |
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); | |
delete this; | |
return lres; | |
case WM_PAINT: | |
OnPaint(); | |
return 0; | |
case WM_PRINTCLIENT: | |
OnPrintClient(reinterpret_cast<HDC>(wParam)); | |
return 0; | |
} | |
return DefWindowProc(m_hwnd, uMsg, wParam, lParam); | |
} | |
void Window::OnPaint() | |
{ | |
PAINTSTRUCT ps; | |
BeginPaint(m_hwnd, &ps); | |
PaintContent(&ps); | |
EndPaint(m_hwnd, &ps); | |
} | |
void Window::OnPrintClient(HDC hdc) | |
{ | |
PAINTSTRUCT ps; | |
ps.hdc = hdc; | |
GetClientRect(m_hwnd, &ps.rcPaint); | |
PaintContent(&ps); | |
} | |
class RootWindow : public Window | |
{ | |
public: | |
virtual LPCTSTR ClassName() { return TEXT("Scratch"); } | |
static RootWindow *Create(); | |
protected: | |
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); | |
LRESULT OnCreate(); | |
private: | |
HWND m_hwndChild; | |
}; | |
LRESULT RootWindow::OnCreate() | |
{ | |
this->m_hwndChild = CreateWindowEx( | |
0, /*dwExStyle*/ | |
WC_LISTVIEW, | |
TEXT("List view"), | |
WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | LVS_REPORT | LVS_SHOWSELALWAYS, /*dwStyle*/ | |
0, | |
0, | |
0, // width | |
0, // height | |
this->m_hwnd, // parent | |
NULL, // menu or control id | |
g_hinst, | |
NULL // lparam | |
); | |
if (! this->m_hwndChild) { | |
return -1; | |
} | |
ListView_SetExtendedListViewStyleEx(this->m_hwndChild, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); | |
LVCOLUMN column; | |
column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; | |
column.fmt = LVCFMT_LEFT; | |
column.iSubItem = 0; | |
column.pszText = TEXT("Column"), | |
column.cx = 50; | |
if (-1 == ListView_InsertColumn(this->m_hwndChild, 0, &column)) { | |
return -1; | |
} | |
LVITEM lvins; | |
lvins.iItem = INT_MAX; // after every existing item; actual index will be returned | |
lvins.mask = LVIF_TEXT; | |
lvins.iSubItem = 0; | |
lvins.pszText = TEXT("One"); | |
if (-1 == ListView_InsertItem(this->m_hwndChild, &lvins)) { | |
return -1; | |
} | |
lvins.pszText = TEXT("Two"); | |
if (-1 == ListView_InsertItem(this->m_hwndChild, &lvins)) { | |
return -1; | |
} | |
lvins.pszText = TEXT("Three"); | |
if (-1 == ListView_InsertItem(this->m_hwndChild, &lvins)) { | |
return -1; | |
} | |
lvins.pszText = TEXT("Four"); | |
if (-1 == ListView_InsertItem(this->m_hwndChild, &lvins)) { | |
return -1; | |
} | |
lvins.pszText = TEXT("Five"); | |
if (-1 == ListView_InsertItem(this->m_hwndChild, &lvins)) { | |
return -1; | |
} | |
lvins.pszText = TEXT("Six"); | |
if (-1 == ListView_InsertItem(this->m_hwndChild, &lvins)) { | |
return -1; | |
} | |
return 0; | |
} | |
LRESULT RootWindow::HandleMessage( | |
UINT uMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
switch (uMsg) { | |
case WM_CREATE: | |
return OnCreate(); | |
case WM_NCDESTROY: | |
// Death of the root window ends the thread | |
PostQuitMessage(0); | |
break; | |
case WM_SIZE: | |
if (m_hwndChild) { | |
SetWindowPos(m_hwndChild, NULL, 0, 0, | |
GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), | |
SWP_NOZORDER | SWP_NOACTIVATE); | |
} | |
return 0; | |
case WM_SETFOCUS: | |
if (m_hwndChild) { | |
SetFocus(m_hwndChild); | |
} | |
return 0; | |
case WM_COMMAND: | |
switch (LOWORD(wParam)) { | |
case IDM_SELECTRANDOM: | |
for (int index = ListView_GetNextItem(this->m_hwndChild, -1, LVNI_SELECTED); index != -1; | |
index = ListView_GetNextItem(this->m_hwndChild, index, LVNI_SELECTED)) { | |
ListView_SetItemState(this->m_hwndChild, index, 0, LVNI_SELECTED); | |
} | |
int index = rand() % ListView_GetItemCount(this->m_hwndChild); | |
ListView_SetItemState(this->m_hwndChild, index, LVNI_SELECTED, LVNI_SELECTED); | |
ListView_SetSelectionMark(this->m_hwndChild, index); | |
ListView_EnsureVisible(this->m_hwndChild, index, false); | |
SetFocus(this->m_hwndChild); | |
return 0; | |
} | |
break; | |
} | |
return __super::HandleMessage(uMsg, wParam, lParam); | |
} | |
RootWindow *RootWindow::Create() | |
{ | |
RootWindow *self = new RootWindow(); | |
if (self && self->WinCreateWindow(0, | |
TEXT("Scratch"), WS_OVERLAPPEDWINDOW, | |
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | |
NULL, NULL)) { | |
return self; | |
} | |
delete self; | |
return NULL; | |
} | |
int PASCAL | |
WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int nShowCmd) | |
{ | |
g_hinst = hinst; | |
if (SUCCEEDED(CoInitialize(NULL))) { | |
InitCommonControls(); | |
RootWindow *prw = RootWindow::Create(); | |
ACCEL accel[1]; | |
accel[0].fVirt = FCONTROL | FVIRTKEY; | |
accel[0].key = 'R'; | |
accel[0].cmd = IDM_SELECTRANDOM; | |
HACCEL haccel = CreateAcceleratorTable(accel, 1); | |
if (prw) { | |
ShowWindow(prw->GetHWND(), nShowCmd); | |
MSG msg; | |
while (GetMessage(&msg, NULL, 0, 0)) { | |
if (!TranslateAccelerator(prw->GetHWND(), haccel, &msg)) { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
} | |
DestroyAcceleratorTable(haccel); | |
CoUninitialize(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment