Access violation on a private array inside a class - c++

For the most part this is borrowed code from RasterTeks DX11 tutorial that I am modified lightly or my own use and taste. I am getting a read access violation while using the below InputClass to set keystates.
#include "InputClass.h"
InputClass::InputClass() { }
InputClass::InputClass(const InputClass& other) { }
InputClass::~InputClass() { }
void InputClass::Initialize() {
// Initialize all the keys to being released and not pressed.
for (int i = 0; i<256; i++) {
keystate[i] = false;
}
return;
}
void InputClass::KeyDown(unsigned int input) {
// If a key is pressed then save that state in the key array.
keystate[input] = true;
return;
}
void InputClass::KeyUp(unsigned int input) {
// If a key is released then clear that state in the key array.
keystate[input] = false;
return;
}
bool InputClass::IsKeyDown(unsigned int input) {
// Return what state the key is in (pressed/not pressed).
return keystate[input];
}
Below is my main callback loop, the one registered with the WindowClass:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// this message is read when the window is closed
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE: {
PostQuitMessage(0);
return 0;
}
default: { return ApplicationHandle->MessageHandler(hWnd, message, wParam, lParam); }
}
}
Finally, below is the secondary message handler that is a part of my SystemClass:
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_KEYDOWN: { input->KeyDown((unsigned int)wparam); }
case WM_KEYUP: { input->KeyUp((unsigned int)wparam); }
default: { return DefWindowProc(hwnd, message, wparam, lparam); }
}
}
The exception is fired off when the code gets to my switch/case/default list in the secondary message handler. If I comment these lines out the program happily runs but of course, no input.
Any help or clues would be invaluable. Thank you so much for your time.

Try following modification of your code:
void InputClass::KeyDown(unsigned int input) {
if (input < 0 || input > 255)
return;
// If a key is pressed then save that state in the key array.
keystate[input] = true;
return;
}
void InputClass::KeyUp(unsigned int input) {
if (input < 0 || input > 255)
return;
// If a key is released then clear that state in the key array.
keystate[input] = false;
return;
}
(since you haven't any problems in constructor of InputClass, it is not a problem of private status of array)

I tried it with no luck. I will leave the code in just in case of error, but it called an access violation in the same place.
I will include missing information below.
//inputclass.h
class InputClass
{
public:
InputClass();
InputClass(const InputClass&);
~InputClass();
void Initialize();
void KeyDown(unsigned int);
void KeyUp(unsigned int);
bool IsKeyDown(unsigned int);
//private:
bool keystate[256];
};
//systemclass.h
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <windowsx.h>
#include "InputClass.h"
class SystemClass {
public:
SystemClass();
~SystemClass();
void Startup();
bool InitializeWindows(HWND);
void ShutDown();
void Run();
LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
int GetWindowPosX();
int GetWindowPosY();
int GetWindowWidth();
int GetWindowHeight();
private:
HWND hWnd;
InputClass* input;
int posX, posY, windowWidth, windowHeight;
};
static SystemClass* ApplicationHandle = 0;
//main.cpp
#include "systemclass.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviousInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
SystemClass* system;
system = new SystemClass;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"Engine";
RegisterClassEx(&wc);
system->Startup();
if(!(system->InitializeWindows(CreateWindowEx(NULL,
L"Engine",
L"Engine",
WS_POPUP | WS_VISIBLE,
system->GetWindowPosX(),
system->GetWindowPosY(),
system->GetWindowWidth(),
system->GetWindowHeight(),
NULL,
NULL,
hInstance,
NULL)))) return 0;
system->Run();
system->ShutDown();
UnregisterClass(L"Engine", hInstance);
delete system;
system = 0;
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// this message is read when the window is closed
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE: {
PostQuitMessage(0);
return 0;
}
default: { return ApplicationHandle->MessageHandler(hWnd, message, wParam, lParam); }
}
}
//systemclass.cpp
#include "SystemClass.h"
SystemClass::SystemClass() { }
SystemClass::~SystemClass() { }
void SystemClass::Startup() {
ApplicationHandle = this;
windowWidth = GetSystemMetrics(SM_CXSCREEN);
windowHeight = GetSystemMetrics(SM_CYSCREEN);
input = new InputClass;
input->Initialize();
int fc = MessageBox(NULL, L"Engine", L"Fullscreen?", MB_YESNO);
switch (fc) {
case 7: {
posX = (windowWidth - 800) / 2;
posY = (windowHeight - 600) / 2;
windowWidth = 800;
windowHeight = 600;
}
case 6: {
DEVMODE dmScreenSettings;
posX = posY = 0;
ZeroMemory(&dmScreenSettings, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)windowWidth;
dmScreenSettings.dmPelsHeight = (unsigned long)windowHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Change the display settings to full screen.
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
}
}
bool SystemClass::InitializeWindows(HWND ihWnd) {
hWnd = ihWnd;
if (hWnd) {
//system->InitializeWindows(hWnd);
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
return true;
}
else {
MessageBoxEx(NULL, L"Could not create window.", L"ERROR!", MB_OK | MB_ICONEXCLAMATION, NULL);
return false;
}
}
void SystemClass::ShutDown() {
delete input;
input = 0;
DestroyWindow(hWnd);
hWnd = NULL;
ApplicationHandle = NULL;
}
void SystemClass::Run() {
bool done;
MSG msg;
done = false;
while (!done) {
// Handle the windows messages.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (input->IsKeyDown(VK_ESCAPE)) {
done = true;
MessageBoxEx(NULL, L"input broken.", L"ERROR!", MB_OK | MB_ICONEXCLAMATION, NULL);
}
// If windows signals to end the application then exit out.
if (msg.message == WM_QUIT) { done = true; }
}
}
int SystemClass::GetWindowPosX(){ return posX; }
int SystemClass::GetWindowPosY() { return posY; }
int SystemClass::GetWindowWidth() { return windowWidth; }
int SystemClass::GetWindowHeight() { return windowHeight; }
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_KEYDOWN: { input->KeyDown((unsigned int)wparam); }
case WM_KEYUP: { input->KeyUp((unsigned int)wparam); }
default: { return DefWindowProc(hwnd, message, wparam, lparam); }
}
}
The error message given when when I hit the escape key:
Unhandled exception at 0x00881E08 in DX11 Engine 2.exe: 0xC0000005: Access violation reading location 0x00000004.
OK: this is where it gets interesting, the values in the local field (specific to the second callback function) are as follows:
lparam: 65537
wparam: 27
message: 256
hwnd: 0x01b80460 {unused=???}
this: 0x00000000
The value of hwnd, wparam, and lparam are all displayed in red.
I feel like the values are supposed to tell me something about what is going on here but I just don't really understand. Is there a reason why the variable "this" is set to adress 0x00000000? this is a pointer to an instance of the systemclass... or it's supposed to be.
Also, the unused comment in hwnd throws me off, though I'm not sure what is going wrong there since the program is very clearly at least DETECTING a keypress attributed to the window.
I hope this helps anyone with any ideas.
EDIT: You got me looking for a misused pointer and I discovered it had EVERYTHING to do with the "this" pointer and the way I was using system and ApplicationHandle. I fixed it by changing ApplicationHandle to system and simply using the same pointer everywhere. The way I was using it before was illogical and senseless.
Thank you all for helping me find it!

Related

Why does my StretchDiBits (windows.h) projected the bitmap on screen so slow and strippy?

CreateWindow.h
#pragma once
#include <Windows.h>
#include <iostream>
#include <stdint.h>
#include <cmath>
#include <vector>
#include <sstream>
using namespace std;
struct returncursorposdemcical
{
float x, y;
};
struct CustomImage
{
vector<vector<unsigned>> CImage;
int long height, width;
};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
class window
{
public:
window();
window(const window&) = delete;
window& operator = (const window&) = delete;
~window();
bool windowpro();
void stretchbit();
void backgroundcolor(int R, int G, int B);
private:
};
CreateWindow.cpp
#include "../Header/CreateWindow.h"
WNDCLASS WindowClass = {};
HWND CreateMyWindow;
HDC mydc;
int BitmapWidth;
int BitmapHeight;
RECT ClientRect;
int ClientWidth;
int ClientHeight;
long int buffer_sizes;
void* buffer_memory;
BITMAPINFO buffer_bitmap;
HINSTANCE myhinstance;
window::window()
{
WindowClass.lpszClassName = "Game_Engine";
WindowClass.lpfnWndProc = WindowProc;
WindowClass.hInstance = myhinstance;
WindowClass.hCursor = LoadCursor(0, IDC_CROSS);
RegisterClass(&WindowClass);
CreateMyWindow = CreateWindowEx(0, "Game_Engine", "Program",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, GetModuleHandle(nullptr), 0);
mydc = GetDC(CreateMyWindow);
ShowWindow(CreateMyWindow, SW_SHOWMAXIMIZED);
}
window::~window()
{
std::cout << "destroy";
ReleaseDC(CreateMyWindow, mydc);
UnregisterClass("Game_Engine", myhinstance);
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_MOUSEMOVE:
{
}
case WM_MOUSELEAVE:
{
}
case WM_SIZE:
{
GetClientRect(CreateMyWindow, &ClientRect);
ClientWidth = ClientRect.right - ClientRect.left;
ClientHeight = ClientRect.bottom - ClientRect.top;
BitmapWidth = ClientWidth;
BitmapHeight = ClientHeight;
buffer_sizes = BitmapWidth * BitmapHeight * sizeof(unsigned int);
if (buffer_memory) {
VirtualFree(buffer_memory, 0, MEM_RELEASE);
}
buffer_memory = VirtualAlloc(0, buffer_sizes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
buffer_bitmap.bmiHeader.biSize = sizeof(buffer_bitmap.bmiHeader);
buffer_bitmap.bmiHeader.biWidth = BitmapWidth;
buffer_bitmap.bmiHeader.biHeight = -BitmapHeight;
buffer_bitmap.bmiHeader.biPlanes = 1;
buffer_bitmap.bmiHeader.biBitCount = 24;
buffer_bitmap.bmiHeader.biCompression = BI_RGB;
}
return 0;
case WM_PAINT:
{
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
bool window::windowpro()
{
MSG msg = { };
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) {
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
void window::backgroundcolor(int R, int G, int B)
{
unsigned int* pixel = (unsigned int*)buffer_memory;
for (int y = 0; y < BitmapHeight; y++) {
for (int x = 0; x < BitmapWidth; x++)
{
*pixel++ = (R << 16) + (G << 8) + B;
}
}
}
void window::stretchbit()
{
StretchDIBits(mydc, 0, 0, BitmapWidth, BitmapHeight, 0, 0, ClientWidth, ClientHeight, buffer_memory,&buffer_bitmap,DIB_RGB_COLORS,SRCCOPY);
}
Source.cpp
#include "../WindowStartup/Header/CreateWindow.h"
int main()
{
window mywindow;
bool running = true;
while (running == true)
{
mywindow.backgroundcolor(225, 225, 225);
mywindow.stretchbit();
if (!mywindow.windowpro())
{
running = false;
}
}
return 0;
}
I tried to double buffer it, but it didn't work, I tried using bitblit, but it's the same result. Also, when the window resizing, it's not fully painted. And when the window it's not at the full size, it does not look strippy, so my speculation is that either my program is writing the data to bitmap to slow for the refresh rate, or the bitmap it's copying to screen to slow. Sorry for my bad English, English it's not my first language, and I am new to program.
I fixed, all you have to do is change biBitcounts to 32, I don't know why that works, might be some to do with ARGB, although I am only using RGB which is 24bits or 3 bytes, if someone could explain this why I need to change biBitcounts to 32, that would be nice. Also thanks for all the people in the comment that are trying to help me.

std::atomic_flag throws exception when I try to write to it with std::atomic_flag::test_and_set()

I'm using the winapi to create a window. For ease of use, I want to wrap it in a C++ class.
When the destructor this class is called, I want to delete the window. However, if the window hasn't been loaded by the time the destructor is called, I.E the constructor of my wrapper class is called and immediately followed by the destructor, I have to need to wait for it to load.
To determine whether it's been loaded yet, I'm currently using an std::atomic_flag. I also tried using an atomic_bool but that had the same problem.
The exception is:
Exception thrown: write access violation.
this was nullptr.
It stems from test_and_set, as I said in the title, and happens somewhere in atomic_flag's exchange method.
The atomic_flag varirable is named "windowLoadedYet", and the offending piece of code is:
windowCreatedYet.test_and_set();
windowCreatedYet.notify_one();
Regrettably, This is my minimal producible result. I tried to make a smaller version, using atomic_bool in some test code, but unfortunately that code ran successfully.
#ifndef UNICODE
#define UNICODE
#endif
#include <time.h>
#include <windows.h>
#include <string>
//#include "events.h"
#include <functional>
//#include <opencv2/opencv.hpp>
#include <future>
#include <iostream>
#include <thread>
#include <atomic>
#include <map>
using std::cout;
using std::cin;
//int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {}
struct MirrageWindow {
MirrageWindow(HINSTANCE hInstance) : hInstance(hInstance){
activeInstancesLedger[hwnd] = this;
//cout << "thread id: " << std::this_thread::get_id() << "\n";
//std::jthread myThread(&MirrageWindow::maintainTheWindow, this);
//maintainTheWindow();
windowThread = std::jthread(&MirrageWindow::setup, this);
}
~MirrageWindow() {
if (!invalidated) {
activeInstancesLedger.erase(hwnd);
windowCreatedYet.wait(false);
SendMessageA(hwnd, WM_DESTROY, NULL, NULL);
cout << "posted message\n";
}
}
MirrageWindow(const MirrageWindow& other) = delete;
private:
bool invalidated = false;
HINSTANCE hInstance;
HWND hwnd = NULL;
std::atomic_flag windowCreatedYet = ATOMIC_FLAG_INIT;
std::jthread windowThread;
LRESULT CALLBACK windowProcessMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
//cout << "Message Recieved, loud and clear.\n";
switch (uMsg)
{
case WM_CREATE:
//std::this_thread::sleep_for(std::chrono::seconds(1));
//windowCreatedYet = false;
windowCreatedYet.test_and_set();
windowCreatedYet.notify_one();
return 0;
case WM_DESTROY:
cout << "Quit message received\n";
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
HBRUSH myCol = CreateSolidBrush(RGB(1, 255, 255));
FillRect(hdc, &ps.rcPaint, myCol);
RECT b{ 0,0,90,200 };
//DrawText(hdc,L"It is disappointing when the toys you love don't love you back. This was Andy's struggle.",-1,&b, DT_BOTTOM | DT_WORDBREAK);
EndPaint(hwnd, &ps);
return 0;
}
case WM_NCHITTEST: {
std::string a = "hi";
time_t t = time(NULL);
a += std::to_string(t);
SetWindowTextA(hwnd, a.c_str());
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
HBRUSH filler = CreateSolidBrush(RGB(255, 255, 0));
FillRect(hdc, &ps.rcPaint, filler);
DeleteObject(filler);
RECT b{ 0,0,90,200 };
DrawText(hdc, L"You clicked. I knew you would.", -1, &b, DT_BOTTOM | DT_WORDBREAK);
EndPaint(hwnd, &ps);
return 0;
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void registerWindowClassIfNotRegistered() {
if (windowClasses.find(hInstance)==windowClasses.end()) {
static uint_fast32_t id_counter = 0;
id_counter++;
std::wstring className = L"Class for Mirrage Windows in this hInstance";
className+=L" id-num: "+(std::to_wstring(id_counter));
windowClasses[hInstance] = className;
WNDCLASS wc{};
wc.hInstance = hInstance;
wc.lpfnWndProc = &redirectorBecauseFuckC;
wc.lpszClassName = className.c_str();
RegisterClass(&wc);
}
}
void createTheWindow() {
cout << std::string(windowClasses[hInstance].begin(), windowClasses[hInstance].end());
hwnd = CreateWindowEx(
WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW,
windowClasses[hInstance].c_str(),
L"Learn to Program Windows, John.",
WS_POPUP,
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL)
{
throw std::runtime_error("Failed to create window.");
}
SetLayeredWindowAttributes(hwnd, RGB(1, 2, 3), 100, LWA_ALPHA);
ShowWindow(hwnd, SW_SHOW);
}
void maintainTheWindow() {
//cout << "running..\n";
MSG msg = { };
SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE);
SetWindowPos(hwnd, HWND_TOPMOST, -0, 0, GetSystemMetrics(0), GetSystemMetrics(1), SWP_FRAMECHANGED);
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
//cout << "transmitting message\n";
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void setup() {
registerWindowClassIfNotRegistered();
createTheWindow();
maintainTheWindow();
}
static inline std::map<HINSTANCE, std::wstring> windowClasses;
static inline std::map<HWND, MirrageWindow*> activeInstancesLedger;
static LRESULT CALLBACK redirectorBecauseFuckC(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
MirrageWindow* redirect = activeInstancesLedger[hwnd];
return redirect->windowProcessMessage(hwnd, uMsg, wParam, lParam);
}
};
int main() {
HINSTANCE hInstance = GetModuleHandle(NULL);
MirrageWindow myWindow(hInstance);
//std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

Why is the Window not loading ? [Win32] [duplicate]

This question already has an answer here:
Win32 API - RegisterClassEx errors
(1 answer)
Closed 2 years ago.
Hi I am an Beginner learning DirectX 11 Api I have seen tutorial on Youtube and implemented this Wrapper for Windows But the Window is lot Loading The only debug string I get is just the Register Class Failed string in the INIT_WINDOw method . Nothing else Pops up . PLease help me with this .
DX_Wrapper.cpp
#include "Headers/Dx_Wrapper.h"
//Global One For Defining __stdcall for WindowProc
namespace
{
Wrapper* g_wrapper = nullptr;
}
//Main WINDOW Message processing Window Procedure
LRESULT CALLBACK WINDOWPROC(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (g_wrapper) return g_wrapper->MessageProcedure(hwnd, msg, wparam, lparam);
else return DefWindowProc(hwnd, msg, wparam, lparam);
}
//Constructor For the Instance
Wrapper::Wrapper(HINSTANCE hinstance)
{
m_hinstance = hinstance;
m_hwnd = NULL;
m_winheight = 600;
m_winwidth = 800;
m_wintitle = L"DirectX";
m_winstyles = WS_OVERLAPPEDWINDOW;
g_wrapper = this;
}
Wrapper::~Wrapper()
{
}
//Window Loop Manager Attached to the WINDOWPROC function
int32_t Wrapper::Run()
{
MSG message = { 0 };
while (WM_QUIT != message.message)
{
//Message Check If Quit
if (PeekMessage(&message, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
//If Not Quit
else
{
UPDATE_FRM(5.5f);
}
}
return static_cast<int>(message.wParam);
}
bool Wrapper::Init()
{
if (!INIT_WINDOW() == true)
{
return false;
}
return true;
}
LRESULT Wrapper::MessageProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
}
void Wrapper::UPDATE_FRM(float delta_time)
{
}
void Wrapper::RENDER_FRM(float delta_time)
{
}
//Registering Classical Windows Class Function
bool Wrapper::INIT_WINDOW()
{
//THE CLASS REGISTERING STUFF
WNDCLASSEX win_class;
win_class.cbClsExtra = 0;
win_class.hInstance = m_hinstance;
win_class.cbWndExtra = 0;
win_class.style = CS_HREDRAW | CS_VREDRAW;
win_class.cbSize = sizeof(WNDCLASSEX);
win_class.lpfnWndProc = WINDOWPROC;
win_class.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
win_class.lpszMenuName = NULL;
win_class.lpszClassName = L"dx_main_class";
win_class.hCursor = 0;
RegisterClassEx(&win_class);
if (!RegisterClassEx(&win_class))
{
OutputDebugString(L"Registering Class Failed");
return false;
}
RECT r = {0,0,m_winwidth,m_winheight};
AdjustWindowRect(&r, m_winstyles, FALSE);
uint_fast16_t f_width = r.right - r.left;
uint_fast16_t f_height = r.bottom - r.top;
uint_fast16_t f_width_final = uint_fast16_t(GetSystemMetrics(SM_CXSCREEN) / 2 - f_width / 2);
uint_fast16_t f_height_final = uint_fast16_t(GetSystemMetrics(SM_CYSCREEN) / 2 - f_height / 2);
m_hwnd = CreateWindow(L"dx_main_class", m_wintitle, m_winstyles, f_width_final, f_height_final, f_width, f_height, NULL, NULL, m_hinstance, NULL);
if (!m_hwnd)
{
OutputDebugString(L"Window Could Not be Created ");
return false;
}
ShowWindow(m_hwnd, SW_SHOW);
return true;
}
DX_Wrapper.h
#include <Windows.h>
#include <stdint.h>
#include <string>
#define WIN32_LEAN_AND_MEAN
class Wrapper
{
public:
Wrapper(HINSTANCE hinstance);
virtual ~Wrapper();
int32_t Run();
virtual bool Init();
virtual LRESULT MessageProcedure(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
virtual void UPDATE_FRM(float delta_time) = 0;
virtual void RENDER_FRM(float delta_time) = 0;
protected:
HWND m_hwnd = nullptr;
HINSTANCE m_hinstance = nullptr;
uint_fast16_t m_winwidth = 0;
uint_fast16_t m_winheight = 0;
LPCWSTR m_wintitle = L"";
DWORD m_winstyles = 0;
protected:
bool INIT_WINDOW();
};
This is the Main Application CPP file
#include "Headers/Dx_Wrapper.h"
class Application : public Wrapper
{
public:
Application(HINSTANCE hinstance);
bool Init() override;
void UPDATE_FRM(float delta_time) override;
void RENDER_FRM(float delta_time) override;
};
Application::Application(HINSTANCE hinstance) : Wrapper(hinstance)
{
}
bool Application::Init()
{
return Wrapper::Init();
}
void Application::UPDATE_FRM(float delta_time)
{
}
void Application::RENDER_FRM(float delta_time)
{
}
int32_t WINAPI WinMain(__in HINSTANCE hinstance, __in_opt HINSTANCE hprevinstance, __in LPSTR cmdline, __in int cmdshow)
{
Application m_app(hinstance);
if (!m_app.Init()) return 1;
return m_app.Run();
}
My Problem is The OutputDebugString Just shows The Registering class failed string from the INIT_WINDOW function . I have no clue why it is wrong . The Window is not running .
First you called twice RegisterClassEx function, so you need to delete the first call:
//RegisterClassEx(&win_class);
if (!RegisterClassEx(&win_class))
{
OutputDebugString(L"Registering Class Failed");
return false;
}
Then you need to set each member of WNDCLASSEX.
So you can refer to the following code:
WNDCLASSEX win_class;
win_class.cbSize = sizeof(WNDCLASSEX);
win_class.style = CS_HREDRAW | CS_VREDRAW;
win_class.lpfnWndProc = WINDOWPROC;
win_class.cbClsExtra = 0;
win_class.cbWndExtra = 0;
win_class.hInstance = m_hinstance;
win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
win_class.hCursor = 0;
win_class.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
win_class.lpszMenuName = NULL;
win_class.lpszClassName = L"dx_main_class";
win_class.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

Cannot open include file: 'basewin.h': No such file or directory

I'm trying to figure out how I can find where to either download the file set or get rid of this error. This elusive 'basewin.h' is nowhere to be found. So I don't know if I'm missing a library or what. I've also tried switching around the 'windows.h' and 'basewin.h' statements. I've tried disabling precompiled headers. Apparently this file holds the information for the "basewindow" class.
I'm using visual studio 2013 and I'm using a win32 project.I'm trying to run the example from the microsoft tutorial website http://msdn.microsoft.com/en-us/library/windows/desktop/ff684181(v=vs.85).aspx. Any help would be very much appreciated. Here is the code:
#include <windows.h>
#include <d2d1.h>
#pragma comment(lib, "d2d1")
#include "basewin.h"
template <class T> void SafeRelease(T **ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
class MainWindow : public BaseWindow<MainWindow>
{
ID2D1Factory *pFactory;
ID2D1HwndRenderTarget *pRenderTarget;
ID2D1SolidColorBrush *pBrush;
D2D1_ELLIPSE ellipse;
void CalculateLayout();
HRESULT CreateGraphicsResources();
void DiscardGraphicsResources();
void OnPaint();
void Resize();
public:
MainWindow() : pFactory(NULL), pRenderTarget(NULL), pBrush(NULL)
{
}
PCWSTR ClassName() const { return L"Circle Window Class"; }
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
};
// Recalculate drawing layout when the size of the window changes.
void MainWindow::CalculateLayout()
{
if (pRenderTarget != NULL)
{
D2D1_SIZE_F size = pRenderTarget->GetSize();
const float x = size.width / 2;
const float y = size.height / 2;
const float radius = min(x, y);
ellipse = D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius);
}
}
HRESULT MainWindow::CreateGraphicsResources()
{
HRESULT hr = S_OK;
if (pRenderTarget == NULL)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
hr = pFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(m_hwnd, size),
&pRenderTarget);
if (SUCCEEDED(hr))
{
const D2D1_COLOR_F color = D2D1::ColorF(1.0f, 1.0f, 0);
hr = pRenderTarget->CreateSolidColorBrush(color, &pBrush);
if (SUCCEEDED(hr))
{
CalculateLayout();
}
}
}
return hr;
}
void MainWindow::DiscardGraphicsResources()
{
SafeRelease(&pRenderTarget);
SafeRelease(&pBrush);
}
void MainWindow::OnPaint()
{
HRESULT hr = CreateGraphicsResources();
if (SUCCEEDED(hr))
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, &ps);
pRenderTarget->BeginDraw();
pRenderTarget->Clear( D2D1::ColorF(D2D1::ColorF::SkyBlue) );
pRenderTarget->FillEllipse(ellipse, pBrush);
hr = pRenderTarget->EndDraw();
if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
{
DiscardGraphicsResources();
}
EndPaint(m_hwnd, &ps);
}
}
void MainWindow::Resize()
{
if (pRenderTarget != NULL)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);
pRenderTarget->Resize(size);
CalculateLayout();
InvalidateRect(m_hwnd, NULL, FALSE);
}
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow)
{
MainWindow win;
if (!win.Create(L"Circle", WS_OVERLAPPEDWINDOW))
{
return 0;
}
ShowWindow(win.Window(), nCmdShow);
// Run the message loop.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
if (FAILED(D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory)))
{
return -1; // Fail CreateWindowEx.
}
return 0;
case WM_DESTROY:
DiscardGraphicsResources();
SafeRelease(&pFactory);
PostQuitMessage(0);
return 0;
case WM_PAINT:
OnPaint();
return 0;
case WM_SIZE:
Resize();
return 0;
}
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
The page you linked says: "The program re-uses the BaseWindow class that was defined in the topic Managing Application State".
That link contains the code for the BaseWindow class, which you should put in basewin.h.

WinAPI DestroyWindow not working

I have this class:
WNDCLASSEX ActionButton::m_wndClass = CreateWndClass();
ActionButton::ActionButton() :
m_function(NULL), m_parameters(NULL), m_window()
{}
ActionButton::~ActionButton()
{
DestroyWindow(m_window);
}
bool ActionButton::DestroyButton()
{
return DestroyWindow(m_window);
}
bool ActionButton::Create(HWND parent, int x, int y, int heigth, int width)
{
HWND m_window = CreateWindowEx(0, L"Action button", NULL, WS_CHILD | WS_VISIBLE,
x, y, width, heigth, parent, NULL, NULL, NULL);
if (m_window == NULL)
return false;
SetWindowLongPtr(m_window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
return true;
}
void ActionButton::SetFuncionLeftButtonDown(CallbackFunction f)
{
m_function = f;
}
void ActionButton::SetParametersLeftButtonDown(void* param)
{
m_parameters = param;
}
WNDCLASSEX ActionButton::CreateWndClass()
{
WNDCLASSEX m_wndClass = {0};
if (m_wndClass.cbSize == 0)
{
m_wndClass.cbSize = sizeof(WNDCLASSEX);
m_wndClass.style = CS_NOCLOSE;
m_wndClass.lpfnWndProc = WndProc;
m_wndClass.cbClsExtra = 0;
m_wndClass.cbWndExtra = 0;
m_wndClass.hInstance = GetModuleHandle(NULL);
m_wndClass.hIcon = NULL;
m_wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
m_wndClass.hbrBackground = HBRUSH(COLOR_BACKGROUND);
m_wndClass.lpszMenuName = NULL;
m_wndClass.lpszClassName = L"Action button";
m_wndClass.hIconSm = NULL;
}
RegisterClassEx(&m_wndClass);
return m_wndClass;
}
LRESULT __stdcall ActionButton::WndProc (HWND window, UINT msg, WPARAM wp, LPARAM lp)
{
ActionButton* classInfo = reinterpret_cast<ActionButton *>(GetWindowLongPtr(window, GWLP_USERDATA));
switch(msg)
{
case WM_LBUTTONDOWN:
{
(classInfo->m_function)(classInfo->m_parameters, classInfo);
classInfo->DestroyButton();
break;
}
case WM_DESTROY:
{
break;
}
default:
return DefWindowProc(window, msg, wp, lp);
}
return 0;
}
I have found problem, that it do not destroy window, what is more I check with debugger that m_window in destructor and Destroy() methods is NULL.
My code of using this class:
void Function(void* input, ActionButton*)
{
std::cout << "Works :)\n";
}
//....
ActionButton button;
button.Create(Form.Get(), 150,150, 50,50);
button.SetFuncionLeftButtonDown(Function);
HWND m_window
That declares a local variable which hides the class member variable. Your compiler should be warning you about this. Pay attention to the warnings.