I'm working on a locker manager app (already did it on console) on win32api. The first build was in "win32 normal style code" (function definitions and declarations, no objects). It was a list view to show items and buttons to interact with it.
Now, this version works like a charm, I fill the listview via LVN_GETDISPINFO notify message and I have a split button which handles the BCN_DROPDOWN notify message as well.
After I saw it working, I wanted to make it encapsulating the windows and controls, and made simple wrappers for listview and button controls.
I handle the very same messages in the same way (LVN_GETDISPINFO and BCN_DROPDOWN notify messages) but in this case, the Listview seems disabled (no change of color), I just can't select anything!.
Now, if I remove the WM_NOTIFY message from the wndproc, and populate the list manually (without dispinfo), it works ok, but as soon as I add the WM_NOTIFY message to handle BCN_DROWDOWN for the split button, things go wrong again, can't select any item.
ListView.cpp:
#include "ListView.h"
#include <vector>
ListView::ListView()
:
hWnd(nullptr), x(0), y(0), width(0), height(0), id(0), nTotalItems(0)/*, lvi({0}), lvc({0})*/
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
}
void ListView::Create(DWORD dwStyle, int x_in, int y_in, int width_in, int height_in, HWND hWndParent, int id_in)
{
assert(hWnd == nullptr);
x = x_in;
y = y_in;
width = width_in;
height = height_in;
id = id_in;
hWnd = CreateWindow(WC_LISTVIEW, "", dwStyle, x, y, width, height, hWndParent, (HMENU)id, GetModuleHandle(nullptr), nullptr);
assert(hWnd != 0);
}
BOOL ListView::InsertRows(int nRows)
{
LVITEM lvi = {};
lvi.mask = LVIF_TEXT | LVIF_STATE;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.iSubItem = 0;
lvi.stateMask = 0;
lvi.state = 0;
for(int i = 0; i < nRows; ++i)
{
lvi.iItem = i;
if(ListView_InsertItem(hWnd, &lvi) == -1)
return FALSE;
}
return TRUE;
}
BOOL ListView::InsertColumns(int nCols)
{
LVCOLUMN lvc = {};
char textCol[] = "Columna";
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.cx = 100;
lvc.pszText = textCol;
lvc.fmt = LVCFMT_LEFT;
for(int i = 0; i < nCols; ++i)
{
lvc.iSubItem = i;
if(ListView_InsertColumn(hWnd, i, &lvc) == -1)
return FALSE;
}
return TRUE;
}
void ListView::SetSubItemText(int nRow, int nCol, const std::string& strText)
{
std::vector<char> tmpChar(strText.begin(), strText.end());
tmpChar.push_back('\0');
ListView_SetItemText(hWnd, nRow, nCol, &tmpChar[0]);
}
void ListView::SetSubItemText(int nRow, int nCol, char * szText)
{
ListView_SetItemText(hWnd, nRow, nCol, szText);
}
void ListView::SetExStyle(DWORD dwExStyle)
{
ListView_SetExtendedListViewStyle(hWnd, dwExStyle);
}
HWND ListView::Hwnd() const
{
return this->hWnd;
}
ListView.h
#ifndef _LISTVIEW_H_
#define _LISTVIEW_H_
#include "../stdafx.h"
#include <CommCtrl.h>
#include <cassert>
#include <string>
class ListView
{
public:
ListView();
void Create(DWORD dwStyle, int x_in, int y_in, int width_in, int height_in, HWND hWndParent, int id_in);
BOOL InsertRows(int nRows);
BOOL InsertColumns(int nCols);
void SetSubItemText(int nRow, int nCol, const std::string& strText);
void SetSubItemText(int nRow, int nCol, char* szText);
std::string GetSubItemText(int nRow, int nCol) const;
void SetExStyle(DWORD dwExStyle);
HWND Hwnd() const;
public:
private:
HWND hWnd;
int id;
int x;
int y;
int width;
int height;
int nTotalItems;
};
#endif
MainWindow.cpp
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
OnCreate();
return 0;
}
break;
case WM_COMMAND:
{
if(HIWORD(wParam) == BN_CLICKED)
OnCommand(LOWORD(wParam));
return 0;
}
break;
case WM_NOTIFY:
{
OnNotify(lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return TRUE;
}
void MainWindow::OnCreate()
{
lvMain.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_ALIGNTOP | LVS_SHOWSELALWAYS | LVS_SINGLESEL,
11, 11, 438, 322, hWnd, ID_LISTVIEW_MAIN);
lvMain.SetExStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
btnAceptar.Create(IDS_ASIGNAR, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | BS_TEXT,
456, 11, hWnd, ID_BUTTON_ASIGNAR);
btnFiltro.Create(IDS_TODOS, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | BS_TEXT | BS_SPLITBUTTON,
456, 41, hWnd, ID_BUTTON_VERTODOS);
const int nColsWidths[] = { 50, 250, 80, 20, 20 };
lvMain.InsertColumns(3);
lvMain.InsertRows(3);
EnumChildWindows(hWnd, SetChildWndFontProc, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
}
void MainWindow::OnCommand(WORD wCmdId)
{
switch (wCmdId)
{
case ID_BUTTON_ASIGNAR:
{
MessageBox(Window(), "hola mundo!", "info", MB_OK);
}
break;
}
}
void MainWindow::OnNotify(LPARAM lParam)
{
switch ( ((LPNMHDR)lParam)->code)
{
case BCN_DROPDOWN:
{
if (((NMBCDROPDOWN*)lParam)->hdr.hwndFrom == btnFiltro.Hwnd())
{
RECT rcButton;
GetClientRect(btnFiltro.Hwnd(), &rcButton);
POINT pt;
pt.x = rcButton.left;
pt.y = rcButton.bottom;
ClientToScreen(btnFiltro.Hwnd(), &pt);
// Create a menu and add items.
HMENU hSplitMenu = CreatePopupMenu();
char szStringBuffer[255];
LoadStringA(GetModuleHandle(nullptr), IDS_ASIGNADOS, szStringBuffer, 255);
AppendMenu(hSplitMenu, MF_BYPOSITION, ID_MENU_VERASIGNADOS, szStringBuffer);
LoadStringA(GetModuleHandle(nullptr), IDS_SINASIGNAR, szStringBuffer, 255);
AppendMenu(hSplitMenu, MF_BYPOSITION, ID_MENU_VERSINASIGNAR, szStringBuffer);
// Display the menu.
TrackPopupMenu(hSplitMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_VERPOSANIMATION, pt.x, pt.y, 0, hWnd, NULL);
}
}
break;
case LVN_GETDISPINFO:
{
if (((LPNMHDR)lParam)->hwndFrom == lvMain.Hwnd() )
{
NMLVDISPINFO* plvdi = (NMLVDISPINFO*)lParam;
switch (plvdi->item.iSubItem)
{
case 0:
{
char buff[100];
strncpy_s(buff, "SubItem Index 0", 100);
plvdi->item.pszText = buff;
}
break;
case 1:
{
char buff[100];
strncpy_s(buff, "SubItem Index 1", 100);
plvdi->item.pszText = buff;
}
break;
case 2:
{
char buff[100];
strncpy_s(buff, "SubItem Index 2", 100);
plvdi->item.pszText = buff;
}
break;
default:
break;
}
}
}
break;
default:
break;
}
}
I'm expecting the same result as using funtcions and global variables to create and control the listview items and subitems. I don't know whats going wrong, Already tried to make the OnNotify handler static, but the same result, Items and subitems are there, but I cant select anything.
Hope you can help me, thank you for your help!.
By the way, this is the code that works ok:
Main.h
#ifndef _MAIN_H_
#define _MAIN_H_
//#define NDEBUG // for assert
//#define UNICODE
#define _WIN32_IE 0x0601
#define _WIN32_WINNT 0x0601
#include <sdkddkver.h>
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <commctrl.h>
#include <cassert>
#include "LM/CLockManager.h"
#include "resource.h"
#define ID_LISTVIEW 1200
#define ID_BUTTON_ASIGNAR 1201
#define ID_BUTTON_VER_TODOS 1202
#define ID_BUTTON_BUSCAR 1203
#define ID_BUTTON_ELIMINAR 1204
#define ID_BUTTON_AGREGAR 1205
#define ID_MENU_VER_ASIGNADOS 1300
#define ID_MENU_VER_SIN_ASIGNAR 1301
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND CreateListView(HWND hWndParent);
HWND CreateButton(HWND hWndParent, const char* szBtnText, int x, int y, int id, DWORD dwStyle = 0);
BOOL InsertListViewColumns(HWND hWndLv_, int nColumns);
BOOL InsertListViewItem(HWND hWndLv_, unsigned int cItems);
BOOL InsertListViewRow(HWND hWndLv_, unsigned int nRows, unsigned int nCols);
void HandleWM_NOTIFY(LPARAM lParam);
#endif
WndProc.cpp
#include "main.h"
#include <string>
#include <vector>
#include <stdexcept>
char szDialogContent[256] = {};
HIMAGELIST hImage = nullptr;
HWND hWndTest = nullptr;
char columnas[3][255] =
{
{"Col 1"},
{"Col 2"},
{"Col 3"}
};
CLockManager manager("basedatos.txt");
std::vector<CLockers> lockers;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
manager.GetLockers(lockers, CLockers::Filter::All);
char szStringBuffer[256];
LoadString(GetModuleHandle(nullptr), IDS_ASIGNAR, szStringBuffer, 255);
HWND hWndBt = CreateButton(hWnd, szStringBuffer, 456, 11, ID_BUTTON_ASIGNAR);
LoadString(GetModuleHandle(nullptr), IDS_TODOS, szStringBuffer, 255);
HWND hWndBt2 = CreateButton(hWnd, szStringBuffer, 456, 41, ID_BUTTON_VER_TODOS, BS_SPLITBUTTON);
LoadString(GetModuleHandle(nullptr), IDS_BUSCAR, szStringBuffer, 255);
HWND hWndBt3 = CreateButton(hWnd, szStringBuffer, 456, 71, ID_BUTTON_BUSCAR);
LoadString(GetModuleHandle(nullptr), IDS_ELIMINAR, szStringBuffer, 255);
HWND hWndBt4 = CreateButton(hWnd, szStringBuffer, 456, 101, ID_BUTTON_ELIMINAR);
LoadString(GetModuleHandle(nullptr), IDS_AGREGAR, szStringBuffer, 255);
HWND hWndBt5 = CreateButton(hWnd, szStringBuffer, 456, 131, ID_BUTTON_AGREGAR);
HWND hWndLv = CreateListView(hWnd);
hImage = ImageList_Create(16, 16, ILC_COLOR32, 1, 1);
HICON hIcon = LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_ICONLOCKER));
ImageList_AddIcon(hImage, hIcon);
DestroyIcon(hIcon);
hIcon = LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_ICONDISABLED));
ImageList_AddIcon(hImage, hIcon);
DestroyIcon(hIcon);
ListView_SetImageList(hWndLv, hImage, LVSIL_SMALL);
BOOL ilvcResult = InsertListViewColumns(hWndLv, 5);
assert(ilvcResult == TRUE);
BOOL ilviResult = InsertListViewItem(hWndLv, lockers.size());
assert(ilviResult == TRUE);
EnumChildWindows(hWnd, SetFontProc, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
}
break;
case WM_COMMAND:
{
if(HIWORD(wParam) == BN_CLICKED)
{
switch(LOWORD(wParam))
{
case ID_BUTTON_VER_TODOS:
{
}
break;
case ID_MENU_VER_ASIGNADOS:
{
}
break;
case ID_MENU_VER_SIN_ASIGNAR:
{
}
break;
case ID_BUTTON_AGREGAR:
{
}
break;
case ID_BUTTON_BUSCAR:
{
}
break;
case ID_BUTTON_ASIGNAR:
{
}
break;
case ID_BUTTON_ELIMINAR:
{
}
break;
}
}
}
break;
case WM_NOTIFY:
switch( ((LPNMHDR)lParam)->code )
{
case LVN_GETDISPINFO:
{
if( ((LPNMHDR)lParam)->hwndFrom == GetDlgItem(hWnd, ID_LISTVIEW) )
{
HandleWM_NOTIFY(lParam);
}
}
break;
case BCN_DROPDOWN:
{
HWND hWndFiltro = GetDlgItem(hWnd, ID_BUTTON_VER_TODOS);
if( ((NMBCDROPDOWN*)lParam)->hdr.hwndFrom == hWndFiltro )
{
RECT rcButton;
GetClientRect(hWndFiltro, &rcButton);
POINT pt;
pt.x = rcButton.left;
pt.y = rcButton.bottom;
ClientToScreen(GetDlgItem(hWnd, ID_BUTTON_VER_TODOS), &pt);
// Create a menu and add items.
HMENU hSplitMenu = CreatePopupMenu();
char szStringBuffer[255];
LoadString(GetModuleHandle(nullptr), IDS_ASIGNADOS, szStringBuffer, 255);
AppendMenu(hSplitMenu, MF_BYPOSITION, ID_MENU_VER_ASIGNADOS, szStringBuffer);
LoadString(GetModuleHandle(nullptr), IDS_SINASIGNAR, szStringBuffer, 255);
AppendMenu(hSplitMenu, MF_BYPOSITION, ID_MENU_VER_SIN_ASIGNAR, szStringBuffer);
// Display the menu.
TrackPopupMenu(hSplitMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_VERPOSANIMATION, pt.x, pt.y, 0, hWnd, NULL);
}
}
break;
}
break;
case WM_DESTROY:
ImageList_Destroy(hImage);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return 0;
}
HWND CreateListView(HWND hWndParent)
{
RECT rcClient = {};
GetClientRect(hWndParent, &rcClient);
HWND hWndLv_ = CreateWindowEx(0, WC_LISTVIEW,
"", WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT |LVS_ALIGNTOP | LVS_SHOWSELALWAYS,
11,11, 438, 322,// rcClient.bottom - rcClient.top - 50,
hWndParent, (HMENU)ID_LISTVIEW, GetModuleHandle(nullptr), nullptr);
ListView_SetExtendedListViewStyle(hWndLv_, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
assert(hWndLv_ != nullptr);
return hWndLv_;
}
HWND CreateButton(HWND hWndParent, const char* szBtnText, int x, int y, int id, DWORD dwStyle)
{
HWND hWndBtn_ = CreateWindow("BUTTON", szBtnText,
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | dwStyle, x, y, 75, 23,
hWndParent, (HMENU)(long long)id, GetModuleHandle(nullptr), nullptr);
assert(hWndBtn_ != nullptr);
return hWndBtn_;
}
BOOL InsertListViewColumns(HWND hWndLv_, int nColumns)
{
LVCOLUMN lvc = {};
int iCol;
int wCols[] = {50, 250, 80, 20, 20};
LoadString(GetModuleHandle(nullptr), IDS_LOCKER, columnas[0], 255);
LoadString(GetModuleHandle(nullptr), IDS_USUARIO, columnas[1], 255);
LoadString(GetModuleHandle(nullptr), IDS_FECHA, columnas[2], 255);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
for(iCol = 0; iCol < nColumns; ++iCol)
{
if(iCol < 1)
{
lvc.fmt = LVCFMT_RIGHT;
}
else
{
lvc.fmt = LVCFMT_LEFT;
}
lvc.iSubItem = iCol;
lvc.pszText = columnas[iCol];
lvc.cx = wCols[iCol];
if (ListView_InsertColumn(hWndLv_, iCol, &lvc) == -1)
return FALSE;
}
return TRUE;
}
BOOL InsertListViewItem(HWND hWndLv_, unsigned int cItems)
{
//HWND hWnd = GetParent(hWndLv_);
LVITEM lvi = {0};
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
lvi.iSubItem = 0;
lvi.stateMask = 0;
lvi.state = 0;
//SendMessage((HWND)hWnd, WM_SETREDRAW, (WPARAM)FALSE, 0);
for(int i = 0; i < cItems; ++i)
{
lvi.iItem = i;
if(!lockers.at(i).Enabled())
lvi.iImage = 1;
else
lvi.iImage = 0;
if(ListView_InsertItem(hWndLv_, &lvi) == -1)
{
return FALSE;
}
}
return TRUE;
}
void HandleWM_NOTIFY(LPARAM lParam)
{
NMLVDISPINFO* plvdi;
switch ( ((LPNMHDR) lParam)->code )
{
case LVN_GETDISPINFO:
{
static constexpr size_t size = 256;
plvdi = (NMLVDISPINFO*)lParam;
switch(plvdi->item.iSubItem)
{
case 0:
{
std::string tmp = std::to_string( lockers.at(plvdi->item.iItem).GetLockerNumber());
char buff[size];
strncpy(buff, tmp.c_str(), size );
plvdi->item.pszText = buff;
}
break;
case 1:
{
std::string tmp = lockers.at(plvdi->item.iItem).GetAssignedUser();
char buff[size];
strncpy(buff, tmp.c_str(), size );
plvdi->item.pszText = buff;
}
break;
case 2:
{
std::string tmp = lockers.at(plvdi->item.iItem).GetDate();
char buff[size];
strncpy(buff, tmp.c_str(), size );
plvdi->item.pszText = buff;
}
break;
case 3:
{
char key[2][2] = {"N", "S"};
plvdi->item.pszText = key[lockers.at(plvdi->item.iItem).HasKey()];
}
break;
case 4:
{
char status[3][2] = {"B", "R", "M"};
plvdi->item.pszText = status[lockers.at(plvdi->item.iItem).GetStatusInt()];
}
break;
default:
break;
}
break;
}
}
}
Ok, I solved it.
Even though, MS Docs state that WM_NOTIFY doesn't return any value "except for notification messages that specify other wise", neither LVN_GETDISPINFO and BCN_DROPDOWN, return any value.
https://learn.microsoft.com/en-us/windows/win32/controls/wm-notify
https://learn.microsoft.com/en-us/windows/win32/controls/bcn-dropdown
https://learn.microsoft.com/en-us/windows/win32/controls/lvn-getdispinfo
So, WM_NOTIFY is supposed to not to return any value, right?....well, everything worked as soon as I added "return 0;" in the WM_NOTIFY case.
Everything is solved now :D I hope this can be useful for someone else
This is the only piece of code that was changed:
on MainWindow.cpp
case WM_NOTIFY:
{
OnNotify(lParam);
return 0;
}
break;
this is the working code in followup to my question. Thank you very much for your help. I hope is not too much code :D (it is the minimun I have, removed resource usage and other non relevant code for the problem):
Main.cpp
#include "stdafx.h"
#include "App.h"
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
App app;
return app.Run();
}
stdafx.h
#pragma once
#define _WIN32_WINNT 0X0601
#include <SDKDDKVer.h>
// Excluir material rara vez utilizado de encabezados de Windows
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef _UNICODE
#undef _UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#define NORPC
#define NOMCX
#define NOTAPE
#define NOKERNEL
#define NOSERVICE
#define NOKANJI
#define NOPROFILER
#define NOPROXYSTUP
#define NOMINMAX
#define STRICT
// Archivos de encabezado de Windows
#include <windows.h>
#include <CommCtrl.h>
#pragma comment(lib, "ComCtl32.lib")
BaseWindow.h
#pragma once
#include "stdafx.h"
#include <cassert>
template <class DERIVED_T>
class BaseWindow
{
public:
BaseWindow() : hWnd(nullptr), hInst(GetModuleHandle(nullptr)), wcx({}) {}
BOOL Create(LPCSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle = 0,
int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int width_in = CW_USEDEFAULT, int height_in = CW_USEDEFAULT,
HWND hWndParent = 0, HMENU hMenu = 0)
{
RECT wr = {};
wr.left = x;
wr.right = width_in + x;
wr.top = y;
wr.bottom = height_in + y;
AdjustWindowRect(&wr, dwStyle, FALSE);
width = wr.right - wr.left;
height = wr.bottom - wr.top;
wcx.cbSize = sizeof(wcx);
wcx.hInstance = hInst;
wcx.lpszClassName = ClassName();
wcx.lpfnWndProc = DERIVED_T::WndProc;
wcx.hbrBackground = (HBRUSH)COLOR_WINDOW;
wcx.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcx.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
ATOM aResult = RegisterClassEx(&wcx);
assert(aResult != 0);
hWnd = CreateWindowEx(
dwExStyle, ClassName(), lpWindowName, dwStyle,
x, y, width, height,
hWndParent, hMenu, hInst, this
);
assert(hWnd != 0);
return (hWnd ? TRUE : FALSE);
}
void Show(int nCmdShow) { ShowWindow(hWnd, nCmdShow); }
HWND Window() const { return hWnd; }
protected:
virtual LPCSTR ClassName() const = 0;
virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
protected:
HWND hWnd;
HINSTANCE hInst;
int width;
int height;
WNDCLASSEX wcx;
public:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
DERIVED_T* pThis = nullptr;
if (uMsg == WM_NCCREATE)
{
CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
pThis = (DERIVED_T*)pCreate->lpCreateParams;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pThis);
pThis->hWnd = hWnd;
}
else
{
pThis = (DERIVED_T*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
}
if (pThis)
{
return pThis->HandleMessage(uMsg, wParam, lParam);
}
else
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
};
MainWindow.h
#pragma once
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include "BaseWindow.h"
#include "button.h"
#include "ListView.h"
class MainWindow : public BaseWindow<MainWindow>
{
public:
MainWindow();
public:
LPCSTR ClassName() const override { return "Window Example"; }
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
static BOOL CALLBACK SetChildWndFontProc(HWND hWndChild, LPARAM font);
private:
void OnCreate();
void OnCommand(WORD wCmdId);
void OnNotify(LPARAM lParam);
private:
enum CONTROLS_ID { ID_LISTVIEW_MAIN = 1200, ID_BUTTON_ASIGNAR, ID_BUTTON_VERTODOS, ID_BUTTON_BUSCAR,
ID_BUTTON_ELIMINAR, ID_BUTTON_AGREGAR, ID_MENU_VERASIGNADOS, ID_MENU_VERSINASIGNAR };
ListView lvMain;
Button btnAceptar;
Button btnFiltro;
char buff[3][255] = {
{"HELLO WORLD!"},
{"HOW ARE YOU?"},
{"FINE, THX!"}
};
};
Mainwindow.cpp
#pragma once
#include "MainWindow.h"
MainWindow::MainWindow()
: BaseWindow<MainWindow>()
{
}
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
OnCreate();
return 0;
}
break;
case WM_COMMAND:
{
if(HIWORD(wParam) == BN_CLICKED)
OnCommand(LOWORD(wParam));
return 0;
}
break;
// here lies the problem
case WM_NOTIFY:
{
OnNotify(lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return TRUE;
}
BOOL CALLBACK MainWindow::SetChildWndFontProc(HWND hWndChild, LPARAM font)
{
SendMessage(hWndChild, WM_SETFONT, (WPARAM)font, TRUE);
return TRUE;
}
void MainWindow::OnCreate()
{
lvMain.Create(WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_ALIGNTOP | LVS_SHOWSELALWAYS | LVS_SINGLESEL,
11, 11, 438, 322, hWnd, ID_LISTVIEW_MAIN);
lvMain.SetExStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
btnAceptar.Create("Asign", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | BS_TEXT,
456, 11, hWnd, ID_BUTTON_ASIGNAR);
btnFiltro.Create("View all", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | BS_TEXT | BS_SPLITBUTTON,
456, 41, hWnd, ID_BUTTON_VERTODOS);
const int nColsWidths[] = { 50, 250, 80 };
lvMain.InsertColumns(3);
lvMain.InsertRows(3);
// Uncomment the following three lines to set manually the subitem text
// and comment the WM_NOTIFY message
// string casted to char* just for testing purposes
//lvMain.SetSubItemText(0, 0, std::string("HELLO WORLD!"));
//lvMain.SetSubItemText(1, 1, (char*)"HOW ARE YOU!?");
//lvMain.SetSubItemText(2, 2, std::string("FINE THX!"));
EnumChildWindows(hWnd, SetChildWndFontProc, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
}
void MainWindow::OnCommand(WORD wCmdId)
{
switch (wCmdId)
{
case ID_BUTTON_ASIGNAR:
{
MessageBox(Window(), "Hello hello!!", "info", MB_OK);
}
break;
}
}
void MainWindow::OnNotify(LPARAM lParam)
{
switch ( ((LPNMHDR)lParam)->code)
{
case BCN_DROPDOWN:
{
if (((NMBCDROPDOWN*)lParam)->hdr.hwndFrom == btnFiltro.Hwnd())
{
RECT rcButton;
GetClientRect(btnFiltro.Hwnd(), &rcButton);
POINT pt;
pt.x = rcButton.left;
pt.y = rcButton.bottom;
ClientToScreen(btnFiltro.Hwnd(), &pt);
// Create a menu and add items.
HMENU hSplitMenu = CreatePopupMenu();
AppendMenu(hSplitMenu, MF_BYPOSITION, ID_MENU_VERASIGNADOS, "menu item 1");
AppendMenu(hSplitMenu, MF_BYPOSITION, ID_MENU_VERSINASIGNAR, "menu item 2");
// Display the menu.
TrackPopupMenu(hSplitMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_VERPOSANIMATION, pt.x, pt.y, 0, hWnd, NULL);
}
}
break;
// parent window receives the LVN_GETDISPINFO msg and populates the list view
// in this example, 3 rows and 3 columns
case LVN_GETDISPINFO:
{
if (((LPNMHDR)lParam)->hwndFrom == lvMain.Hwnd() )
{
NMLVDISPINFO* plvdi = (NMLVDISPINFO*)lParam;
switch (plvdi->item.iSubItem)
{
case 0:
{
char buff[100];
strncpy_s(buff, "SubItem Index 0", 100);
plvdi->item.pszText = buff;
}
break;
case 1:
{
char buff[100];
strncpy_s(buff, "SubItem Index 1", 100);
plvdi->item.pszText = buff;
}
break;
case 2:
{
char buff[100];
strncpy_s(buff, "SubItem Index 2", 100);
plvdi->item.pszText = buff;
}
break;
default:
break;
}
}
}
break;
default:
break;
}
}
App.h
#pragma once
#include "MainWindow.h"
class App
{
public:
App();
App(const App&) = delete;
App& operator=(const App&) = delete;
~App();
int Run();
private:
HINSTANCE hInst;
MainWindow win;
};
App.cpp
#include "App.h"
App::App()
: hInst(GetModuleHandle(nullptr))
{
win.Create("My app", WS_OVERLAPPEDWINDOW, 0, CW_USEDEFAULT, CW_USEDEFAULT, 542, 343);
win.Show(SW_SHOWDEFAULT);
}
App::~App()
{
}
int App::Run()
{
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
Button.h
#ifndef _BUTTON_H_
#define _BUTTON_H_
#include "stdafx.h"
#include <cassert>
class Button
{
public:
Button();
void Create(LPCSTR lpszText, DWORD dwStyle, int x_in, int y_in, HWND hWndParent, int id_in);
void Create(int idString, DWORD dwStyle, int x_in, int y_in, HWND hWndParent, int id_in);
HWND Hwnd() const;
public:
private:
HWND hWnd;
int id;
int x;
int y;
static constexpr int width = 75;
static constexpr int height = 24;
static constexpr int nMaxLoadString = 100;
};
#endif
Button.cpp
#include "Button.h"
Button::Button()
:
hWnd(nullptr), x(0), y(0), id(0)
{
}
void Button::Create(LPCSTR lpszText, DWORD dwStyle, int x_in, int y_in, HWND hWndParent, int id_in)
{
// we don't want to create another button with the same object
assert(hWnd == nullptr);
x = x_in;
y = y_in;
id = id_in;
hWnd = CreateWindow("Button", lpszText, dwStyle, x, y, width, height, hWndParent, (HMENU)id, GetModuleHandle(nullptr), 0);
assert(hWnd != 0);
}
void Button::Create(int idString, DWORD dwStyle, int x_in, int y_in, HWND hWndParent, int id_in)
{
char szButtonName[nMaxLoadString] = {};
LoadString(GetModuleHandle(nullptr), idString, szButtonName, nMaxLoadString);
Create(szButtonName, dwStyle, x_in, y_in, hWndParent, id_in);
}
HWND Button::Hwnd() const
{
return hWnd;
}
ListView.h
#ifndef _LISTVIEW_H_
#define _LISTVIEW_H_
#include "stdafx.h"
#include <CommCtrl.h>
#include <cassert>
#include <string>
class ListView
{
public:
ListView();
void Create(DWORD dwStyle, int x_in, int y_in, int width_in, int height_in, HWND hWndParent, int id_in);
BOOL InsertRows(int nRows);
BOOL InsertColumns(int nCols);
BOOL InsertColumn(int iCol, char* szText, int nWidthCol = 50);
void SetSubItemText(int nRow, int nCol, const std::string& strText);
void SetSubItemText(int nRow, int nCol, char* szText);
std::string GetSubItemText(int nRow, int nCol) const;
void SetExStyle(DWORD dwExStyle);
HWND Hwnd() const;
public:
private:
HWND hWnd;
int id;
int x;
int y;
int width;
int height;
int nTotalItems;
};
#endif
ListView.cpp
#include "ListView.h"
#include <vector>
ListView::ListView()
:
hWnd(nullptr), x(0), y(0), width(0), height(0), id(0), nTotalItems(0)
{
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(icex);
icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
}
void ListView::Create(DWORD dwStyle, int x_in, int y_in, int width_in, int height_in, HWND hWndParent, int id_in)
{
// we don't want to create another listview with the same object
assert(hWnd == nullptr);
x = x_in;
y = y_in;
width = width_in;
height = height_in;
id = id_in;
hWnd = CreateWindow(WC_LISTVIEW, "", dwStyle, x, y, width, height, hWndParent, (HMENU)id, GetModuleHandle(nullptr), nullptr);
assert(hWnd != 0);
}
BOOL ListView::InsertRows(int nRows)
{
LVITEM lvi = {};
lvi.mask = LVIF_TEXT | LVIF_STATE;
// remove LPSTR_TEXTCALLBACK and replace with a non const string if you want
// to manually insert the items and subitems
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.iSubItem = 0;
lvi.stateMask = 0;
lvi.state = 0;
for(int i = 0; i < nRows; ++i)
{
lvi.iItem = i;
if(ListView_InsertItem(hWnd, &lvi) == -1)
return FALSE;
}
return TRUE;
}
BOOL ListView::InsertColumns(int nCols)
{
LVCOLUMN lvc = {};
char textCol[] = "Test name"; // test name for the columns
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.cx = 100; // hardcoded for testing purposes
lvc.pszText = textCol;
lvc.fmt = LVCFMT_LEFT;
for(int i = 0; i < nCols; ++i)
{
lvc.iSubItem = i;
if(ListView_InsertColumn(hWnd, i, &lvc) == -1)
return FALSE;
}
return TRUE;
}
// another method to insert columns
BOOL ListView::InsertColumn(int iCol, char * szText, int nWidthCol)
{
LVCOLUMN lvc = {};
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.cx = nWidthCol;
lvc.pszText = szText;
lvc.iSubItem = iCol;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hWnd, iCol, &lvc) == -1)
return FALSE;
return TRUE;
}
void ListView::SetSubItemText(int nRow, int nCol, const std::string& strText)
{
std::vector<char> tmpChar(strText.begin(), strText.end());
tmpChar.push_back('\0');
ListView_SetItemText(hWnd, nRow, nCol, &tmpChar[0]);
}
void ListView::SetSubItemText(int nRow, int nCol, char * szText)
{
ListView_SetItemText(hWnd, nRow, nCol, szText);
}
void ListView::SetExStyle(DWORD dwExStyle)
{
ListView_SetExtendedListViewStyle(hWnd, dwExStyle);
}
HWND ListView::Hwnd() const
{
return this->hWnd;
}
I am using this website to learn DirectX: http://www.rastertek.com/tutdx10.html I am trying to use their DirectInput tutorial to add more keybindings besides Escape. However, I cannot get my keys to fire. Here is the relevant code:
////////////////////////////////////////////////////////////////////////////////
// Filename: inputclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "inputclass.h"
InputClass::InputClass()
{
m_directInput = 0;
m_keyboard = 0;
m_mouse = 0;
}
InputClass::InputClass(const InputClass& other)
{
}
InputClass::~InputClass()
{
}
bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int screenHeight)
{
HRESULT result;
//Store the screen sizew hcih will be used for positioning the mouse cursor.
m_screenWidth = screenWidth;
m_screenHeight = screenHeight;
//Initialize the location of the mouse on the screen.
m_mouseX = 0;
m_mouseY = 0;
//Initialize the main direct input interface.
result = DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_directInput, NULL);
if(FAILED(result))
{
return false;
}
//Initialize the direct input interface for the keyboard.
result = m_directInput->CreateDevice(GUID_SysKeyboard, &m_keyboard, NULL);
if(FAILED(result))
{
return false;
}
//Set the data format. In this case since it is a keyboard we can use the predefined data format.
result = m_keyboard->SetDataFormat(&c_dfDIKeyboard);
if(FAILED(result))
{
return false;
}
//Set the cooperative level of the keyboard to not share with other programs.
result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
if(FAILED(result))
{
return false;
}
//Now aquire the keyboard.
result = m_keyboard->Acquire();
if(FAILED(result))
{
return false;
}
//Initialize the direct input interface for the mouse.
result = m_directInput->CreateDevice(GUID_SysMouse, &m_mouse, NULL);
if(FAILED(result))
{
return false;
}
//Set the data format for the mouse using the pre-defined mouse data format.
result = m_mouse->SetDataFormat(&c_dfDIMouse);
if(FAILED(result))
{
return false;
}
//Set the cooperative level of the mouse to share with other programs.
result = m_mouse->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
if(FAILED(result))
{
return false;
}
//Aquire the mouse.
result = m_mouse->Acquire();
if(FAILED(result))
{
return false;
}
return true;
}
void InputClass::Shutdown()
{
//Release the mouse.
if(m_mouse)
{
m_mouse->Unacquire();
m_mouse->Release();
m_mouse = 0;
}
//Release the keyboard.
if(m_keyboard)
{
m_keyboard->Unacquire();
m_keyboard->Release();
m_keyboard = 0;
}
//Release the main interface to direct input.
if(m_directInput)
{
m_directInput->Release();
m_directInput = 0;
}
return;
}
bool InputClass::Frame()
{
bool result;
//Read the current state of the keyboard.
result = ReadKeyboard();
if(!result)
{
return false;
}
//Read the current state of the mouse.
result = ReadMouse();
if(!result)
{
return false;
}
//Process the changes in the mouse and keyboard.
ProcessInput();
return true;
}
bool InputClass::ReadKeyboard()
{
HRESULT result;
//Read the keyboard device.
result = m_keyboard->GetDeviceState(sizeof(m_keyboardState), (LPVOID)&m_keyboardState);
if(FAILED(result))
{
//If the keyboard lost focuse or was not aquired then try to get control back.
if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
{
m_keyboard->Acquire();
}
else
{
return false;
}
}
return true;
}
bool InputClass::ReadMouse()
{
HRESULT result;
//Read the mouse device.
result = m_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&m_mouseState);
if(FAILED(result))
{
//If the mouse lost focus or was not aqcuired then try to get control back.
if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
{
m_mouse->Acquire();
}
else
{
return false;
}
}
return true;
}
void InputClass::ProcessInput()
{
//Update the location of the mouse cursor based on the change of the mouse location during the frame.
m_mouseX += m_mouseState.lX;
m_mouseY += m_mouseState.lY;
//Ensure the mouse location doesn't exceed the screen width or height.
if(m_mouseX < 0) {m_mouseX = 0;}
if(m_mouseY < 0) {m_mouseY = 0;}
if(m_mouseX > m_screenWidth) {m_mouseX = m_screenWidth;}
if(m_mouseY > m_screenHeight) {m_mouseY = m_screenHeight;}
return;
}
bool InputClass::IsEscapePressed()
{
//Do a bitwise and on the keyboard state to check if the escape key is currently being pressed.
std::cout << "checking ESCAPE" << std::endl;
if(m_keyboardState[DIK_ESCAPE] & 0x80)
{
std::cout << "ESCAPE" << std::endl;
return true;
}
return false;
}
bool InputClass::IsWPressed()
{
if(m_keyboardState[DIK_W] & 0x80)
{
std::cout << "W" << std::endl;
return true;
}
return false;
}
bool InputClass::IsAPressed()
{
if(m_keyboardState[DIK_A] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsSPressed()
{
if(m_keyboardState[DIK_S] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsDPressed()
{
if(m_keyboardState[DIK_D] & 0x80)
{
return true;
}
return false;
}
void InputClass::GetMouseLocation(int& mouseX, int& mouseY)
{
mouseX = m_mouseX;
mouseY = m_mouseY;
return;
}
Other file:
////////////////////////////////////////////////////////////////////////////////
// Filename: systemclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "systemclass.h"
SystemClass::SystemClass()
{
m_Input = 0;
m_Graphics = 0;
}
SystemClass::SystemClass(const SystemClass& other)
{
}
SystemClass::~SystemClass()
{
}
bool SystemClass::Initialize()
{
int screenWidth, screenHeight;
bool result;
// Initialize the width and height of the screen to zero before sending the variables into the function.
screenWidth = 0;
screenHeight = 0;
// Initialize the windows api.
InitializeWindows(screenWidth, screenHeight);
// Create the input object. This object will be used to handle reading the keyboard input from the user.
m_Input = new InputClass;
if(!m_Input)
{
return false;
}
// Initialize the input object.
result = m_Input->Initialize(m_hinstance, m_hwnd, screenWidth, screenHeight);
if(!result)
{
MessageBox(m_hwnd, L"Could not initialize the input object.", L"Error", MB_OK);
return false;
}
// Create the graphics object. This object will handle rendering all the graphics for this application.
m_Graphics = new GraphicsClass;
if(!m_Graphics)
{
return false;
}
// Initialize the graphics object.
result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd);
if(!result)
{
return false;
}
return true;
}
void SystemClass::Shutdown()
{
// Release the graphics object.
if(m_Graphics)
{
m_Graphics->Shutdown();
delete m_Graphics;
m_Graphics = 0;
}
// Release the input object.
if(m_Input)
{
m_Input->Shutdown();
delete m_Input;
m_Input = 0;
}
// Shutdown the window.
ShutdownWindows();
return;
}
void SystemClass::Run()
{
MSG msg;
bool done, result;
// Initialize the message structure.
ZeroMemory(&msg, sizeof(MSG));
// Loop until there is a quit message from the window or the user.
done = false;
while(!done)
{
// Handle the windows messages.
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// If windows signals to end the application then exit out.
if(msg.message == WM_QUIT)
{
done = true;
}
else
{
// Otherwise do the frame processing.
result = Frame();
if(!result)
{
done = true;
}
}
//Check if the user pressed escape and wants to quit.
if(m_Input->IsEscapePressed() == true)
{
std::cout << "ESCAPE" << std::endl;
done = true;
}
if(m_Input->IsWPressed() == true)
{
m_Graphics->SetCameraPos(0, 1, 0);
std::cout << "W" << std::endl;
}
if(m_Input->IsAPressed() == true)
{
m_Graphics->SetCameraPos(1, 0, 0);
std::cout << "A" << std::endl;
}
if(m_Input->IsSPressed() == true)
{
m_Graphics->SetCameraPos(0, -1, 0);
std::cout << "S" << std::endl;
}
if(m_Input->IsDPressed() == true)
{
m_Graphics->SetCameraPos(-1, 0, 0);
std::cout << "D" << std::endl;
}
}
return;
}
bool SystemClass::Frame()
{
bool result;
int mouseX, mouseY;
//Do the frame processing.
result = m_Input->Frame();
if(!result)
{
return false;
}
//Get the location of the mouse from the input object.
m_Input->GetMouseLocation(mouseX, mouseY);
// Do the frame processing for the graphics object.
result = m_Graphics->Frame(mouseX, mouseY);
if(!result)
{
return false;
}
result = m_Graphics->Render();
if(!result)
{
return false;
}
return true;
}
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
return DefWindowProc(hwnd, umsg, wparam, lparam);
}
void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight)
{
WNDCLASSEX wc;
DEVMODE dmScreenSettings;
int posX, posY;
// Get an external pointer to this object.
ApplicationHandle = this;
// Get the instance of this application.
m_hinstance = GetModuleHandle(NULL);
// Give the application a name.
m_applicationName = L"Engine";
// Setup the windows class with default settings.
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_applicationName;
wc.cbSize = sizeof(WNDCLASSEX);
// Register the window class.
RegisterClassEx(&wc);
// Determine the resolution of the clients desktop screen.
screenWidth = GetSystemMetrics(SM_CXSCREEN);
screenHeight = GetSystemMetrics(SM_CYSCREEN);
// Setup the screen settings depending on whether it is running in full screen or in windowed mode.
if(FULL_SCREEN)
{
// If full screen set the screen to maximum size of the users desktop and 32bit.
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth;
dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Change the display settings to full screen.
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
// Set the position of the window to the top left corner.
posX = posY = 0;
}
else
{
// If windowed then set it to 800x600 resolution.
screenWidth = 800;
screenHeight = 600;
// Place the window in the middle of the screen.
posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2;
posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
}
// Create the window with the screen settings and get the handle to it.
m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
// Bring the window up on the screen and set it as main focus.
ShowWindow(m_hwnd, SW_SHOW);
SetForegroundWindow(m_hwnd);
SetFocus(m_hwnd);
// Hide the mouse cursor.
ShowCursor(false);
return;
}
void SystemClass::ShutdownWindows()
{
// Show the mouse cursor.
ShowCursor(true);
// Fix the display settings if leaving full screen mode.
if(FULL_SCREEN)
{
ChangeDisplaySettings(NULL, 0);
}
// Remove the window.
DestroyWindow(m_hwnd);
m_hwnd = NULL;
// Remove the application instance.
UnregisterClass(m_applicationName, m_hinstance);
m_hinstance = NULL;
// Release the pointer to this class.
ApplicationHandle = NULL;
return;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
switch(umessage)
{
// Check if the window is being destroyed.
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
// All other messages pass to the message handler in the system class.
default:
{
return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam);
}
}
}
Why don't try with GetAsyncKeyState function?
you can put that in your update function and check for the desired key code.
Something like this:
//check if num1 is pressed, if yes switch off the lights.
if(GetAsyncKeyState('1') & 0x8000)
{
mLightCount = 0;
}
As it turned out, the keybindings were working. I tried switching the close key to w and pressing W closed the window. What was wrong was how I was moving the camera. Thanks for helping!