Jump to content
  • Advertisement

Lenox

Member
  • Content Count

    203
  • Joined

  • Last visited

Community Reputation

166 Neutral

About Lenox

  • Rank
    Member
  1. Quote:Original post by iMalc First off, just a bunch of comments on the posted code: Don't check for NULL pointers before deleting them. That check is already the first thing done inside delete itself, so you're just duplicating it. As mentioned, you're better off using std::string anyway. Also, in a destructor there is no point setting the pointers to NULL as the object is being deleted and those pointers are about the cease existing anyway. Those pragma warning disables look a little worrying. It looks like you must have 64-bit compatibility turned on, and then use the pragmas to ignore warnings related to that. Just go into the project settings and turn off the 64-bit compatibility warnings. To get rid of warning 4244, simply comment out the name of unused variables (but leave their type info there) operator == should take a "const Control&" as the right-hand side. Shouldn't IsValidHandler be const, and how about taking a const iterator reference instead of passing by value. This is a rather odd way of doing a strcpy: memset(const_cast<LPSTR>(wndClass.lpszClassName), '\0', strlen(ansi) + 1); memcpy(const_cast<LPSTR>(wndClass.lpszClassName), ansi, strlen(ansi));You've used the same thing a few more times later on. Just use strcpy and wcscpy. Now, once you've dealt with that, would you mind posting the call stack at the point of the the assertion please? Thanks for the input. On the checking for NULL and setting to NULL in my dtors: I did this for safe measure- I don't like to assume that something's going to be valid when I delete it. It just makes me feel better inside. About the operator== and IsValidHandler- Yeah, you're right. My bad. Yeah, I prefer using memset/memcpy. Not quite sure why. I think I'll look into the ramifications of using strcpy over memcpy. My call stack at the time of the assertion looks like this: > GUI.dll!operator delete(void * pUserData=0x00ec1068) Line 52 + 0x51 bytes C++ GUI.dll!RichEditCtl::`vector deleting destructor'() + 0x7d bytes C++ GSEMaster.exe!MainWindow::~MainWindow() Line 19 + 0x6f bytes C++ GSEMaster.exe!MainWindow::`scalar deleting destructor'() + 0x2b bytes C++ ~MainWindow() looks like so: MainWindow::~MainWindow() { if(OutputREC != NULL) { delete OutputREC; /* This line is the one in question */ OutputREC = NULL; } if(InputREC != NULL) { delete InputREC; InputREC = NULL; } if(client != NULL) { delete client; client = NULL; } } And ~Control() now looks like this, after going through a few of the other suggestions: Control::~Control() { if(_ctl_parent) _ctl_parent->Destroy(); if(_name) { delete [] _name; _name = NULL; } if(_class) { if(!_registered) UnregisterClass(_class, _hinst); delete [] _class; _class = NULL; } this->Destroy(); } Quote:Original post by Evil Steve Look up the call stack when that assertion occurs - what line in your code is triggering it? EDIT: Also, you don't seem to be passing the WM_NCCREATE message along to DefWindowProc() (Although it's probably unrelated). EDIT #2: How do you destroy the control? It's possible that the control is being destroyed before the window, which causes weird pointer errors when the wndproc is called (Since it gets the stored pointer and assumes it's valid). Ah, WM_NCCREATE is being passed along to DefWindowProc (or the control's old wndproc, if it had one) unless an exception occurs while I'm trying to handle it. And, after your second edit, I realized I wasn't destroying my controls (Whoops.) and added a few calls to Control::Destroy() in there, which just calls ::DestroyWindow. Quote:Original post by Zahlman Barely skimmed your code, but memory corruption may be a problem. Have you considered using std::(w)string to represent text? You then wouldn't need a destructor at all (unless there's something else you aren't doing in the dtor that you should). Using wchar_t* is just a preference, albeit a foolish one. I'll see what I can do about switching over, though. [EDIT] After I started actually deleting the window properly, the assertion magically disappeared. Thanks, all. [Edited by - Lenox on January 5, 2008 1:08:20 AM]
  2. I'm using an std::map to map Windows Messages to function pointers in my Control class. When my Control is deleted, the Control's dtor is called and the elements from my std::map are removed when it goes out of scope. The problem comes when the final element in my std::map is removed; it ends up failing the following assertion in dbgdel.cpp: ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); So, my question to you guys is: What might be causing this? I'm not doing anything way too strange with my std::map it seems, but I s'pose looks can be deceiving. The relevant code is as follows: Control.h: #ifndef CONTROL_H #define CONTROL_H #include <windows.h> #include <string> #include <map> #include <utility> #include "../GUIDll.h" // warning C4312: 'reinterpret_cast' : conversion from 'LONG' to 'Window *' of greater size #pragma warning( disable: 4312 ) // warning C4311: 'reinterpret_cast' : pointer truncation from 'Window *' to 'LONG' #pragma warning( disable: 4311 ) // warning C4244: 'argument' : conversion from 'LPARAM' to 'long', possible loss of data #pragma warning( disable: 4244 ) // warning C4100: 'lParam' : unreferenced formal parameter #pragma warning( disable: 4100 ) // warning C4127: conditional expression is constant #pragma warning( disable: 4127 ) class Control; typedef long (* MsgHandlerPtr)(Control*, HWND, WPARAM, LPARAM); typedef std::map<long, MsgHandlerPtr> MsgMap; typedef MsgMap::const_iterator MsgIterator; class Control { protected: GUILIB_API MsgHandlerPtr RegisterMsgHandler(long msg, MsgHandlerPtr handler); HWND _hwnd; MsgMap _handlers; HINSTANCE _hinst; unsigned int _style; wchar_t * _name; wchar_t * _class; Control * _ctl_parent; WNDPROC _oldwndproc; HBRUSH _brush; bool _registered; HMENU _menu; bool _vscroll; bool _hscroll; HICON _icon; anchor_point _top_left; anchor_point _bottom_right; double _x; double _y; double _width; double _height; static LRESULT CALLBACK MsgRouter(HWND, UINT, WPARAM, LPARAM); void SetHWND(HWND hWnd) {_hwnd = hWnd; }; public: inline bool operator ==(Control &rhs) { return (_hwnd == rhs._hwnd); } GUILIB_API Control(HINSTANCE hInst, Control * ctlParent = NULL); GUILIB_API virtual ~Control(); GUILIB_API void Create(); GUILIB_API void Focus(); MsgIterator GetMsgHandler(long msg); bool IsValidHandler(MsgIterator iter) { return (iter != _handlers.end()); }; GUILIB_API bool IsControl(HWND hWnd) const { return (hWnd == _hwnd); }; GUILIB_API WNDPROC GetOldWndProc() const { return _oldwndproc; }; GUILIB_API void SetStyle(int style); GUILIB_API void SetClass(char * name); GUILIB_API void SetName(char * name); GUILIB_API void SetClass(wchar_t * name); GUILIB_API void SetName(wchar_t * name); GUILIB_API void SetX(double x = CW_USEDEFAULT); GUILIB_API void SetY(double y = CW_USEDEFAULT); GUILIB_API void SetHeight(double height = CW_USEDEFAULT); GUILIB_API void SetWidth(double width = CW_USEDEFAULT); GUILIB_API void SetMenu(unsigned int hMenu = 0); GUILIB_API void SetMenu(HMENU hMenu = NULL); GUILIB_API void SetBrush(HBRUSH hBrush = NULL); GUILIB_API void SetRegistered(bool registered = false); GUILIB_API void SetVScroll(bool VScroll = false); GUILIB_API void SetHScroll(bool HScroll = false); GUILIB_API void SetIcon(HICON hIcon); GUILIB_API bool HasHandlers() const { return (_handlers.empty() != true); }; GUILIB_API void Destroy(); GUILIB_API unsigned int GetStyle() const { return _style; }; GUILIB_API HWND GetHWND() const { return _hwnd; }; GUILIB_API double GetWidth() const { return _width; } GUILIB_API double GetHeight() const { return _height; } GUILIB_API anchor_point GetTopLeftAnchor() const { return _top_left; }; GUILIB_API anchor_point GetBottomRightAnchor() const { return _bottom_right; }; GUILIB_API void SetAnchors(); }; #endif // CONTROL_H Control.cpp: #include "Control.h" #include "Unicode.h" Control::Control(HINSTANCE hInst, Control * ctlParent) : _hwnd(NULL), _hinst(hInst), _style(0), _name(NULL), _class(NULL), _ctl_parent(ctlParent), _oldwndproc(NULL), _brush(NULL), _registered(false), _menu(NULL), _vscroll(false), _hscroll(false), _icon(NULL), _x(0), _y(0), _width(0), _height(0) { }; Control::~Control() { if(_name != NULL) { delete [] _name; _name = NULL; } if(_class != NULL) { delete [] _class; _class = NULL; } if(_ctl_parent != NULL) _ctl_parent = NULL; } void Control::Create() { if(!_registered) { WNDCLASSEX wndClass; memset(&wndClass, '\0', sizeof(WNDCLASSEX)); wndClass.cbSize = sizeof(wndClass); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = &Control::MsgRouter; wndClass.hInstance = _hinst; wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); if(!_brush) { wndClass.hbrBackground = GetSysColorBrush(COLOR_APPWORKSPACE); _brush = wndClass.hbrBackground; } else { wndClass.hbrBackground = _brush; } wndClass.lpszMenuName = NULL; if(_class != NULL) { #ifndef _UNICODE char * ansi = NULL; UnicodeToAnsi(_class, &ansi); wndClass.lpszClassName = new char[strlen(ansi) + 1]; memset(const_cast<LPSTR>(wndClass.lpszClassName), '\0', strlen(ansi) + 1); memcpy(const_cast<LPSTR>(wndClass.lpszClassName), ansi, strlen(ansi)); CoTaskMemFree(ansi); #else wndClass.lpszClassName = new wchar_t[wcslen(_class) + 1]; wmemset(const_cast<LPWSTR>(wndClass.lpszClassName), '\0', wcslen(_class) + 1); wmemcpy(const_cast<LPWSTR>(wndClass.lpszClassName), _class, wcslen(_class)); #endif } else { wndClass.lpszClassName = NULL; } wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; if(_icon != NULL) { wndClass.hIconSm = _icon; } else { wndClass.hIconSm = reinterpret_cast<HICON>(NULL); } wndClass.hIcon = reinterpret_cast<HICON>(NULL); if(!RegisterClassEx(&wndClass)) throw std::runtime_error("Failed to register the class."); } if(_vscroll) _style |= WS_VSCROLL; if(_hscroll) _style |= WS_HSCROLL; HWND hWnd = ::CreateWindowW(_class, _name, _style, _x, _y, _width, _height, (_ctl_parent != NULL ? _ctl_parent->_hwnd : NULL), _menu, _hinst, reinterpret_cast<LPVOID>(this)); if(!hWnd) throw std::runtime_error("Failed to create the window."); if(_registered) { _oldwndproc = reinterpret_cast<WNDPROC>(::GetWindowLong(hWnd, GWL_WNDPROC)); ::SetWindowLong(hWnd, GWL_WNDPROC, reinterpret_cast<LONG>(&Control::MsgRouter)); ::SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LONG>(this)); SetHWND(hWnd); } } LRESULT CALLBACK Control::MsgRouter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { Control * control = NULL; if(message == WM_NCCREATE) { control = reinterpret_cast<Control*>(((LPCREATESTRUCT)lParam)->lpCreateParams); if(control == NULL) throw std::runtime_error("The instance was not passed to the message router."); ::SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LONG>(control)); control->SetHWND(hWnd); } else { control = reinterpret_cast<Control*>(::GetWindowLong(hWnd, GWL_USERDATA)); if(control == NULL) { return ::DefWindowProc(hWnd, message, wParam, lParam); } } if(control->HasHandlers()) { MsgIterator iter = control->GetMsgHandler(message); if(control->IsValidHandler(iter) == true) return (iter->second)(control, hWnd, wParam, lParam); } if(control->_oldwndproc != NULL) { return (control->_oldwndproc)(hWnd, message, wParam, lParam); } else { return ::DefWindowProc(hWnd, message, wParam, lParam); } } MsgIterator Control::GetMsgHandler(long msg) { return _handlers.find(msg); } MsgHandlerPtr Control::RegisterMsgHandler(long msg, MsgHandlerPtr handler) { MsgHandlerPtr prev = NULL; MsgIterator iter = _handlers.find(msg); if(IsValidHandler(iter)) prev = iter->second; _handlers.insert(std::make_pair<long, MsgHandlerPtr>(msg, handler)); return prev; } void Control::SetRegistered(bool registered) { _registered = registered; } void Control::SetStyle(int style) { _style = style; if(_hwnd) ::SetWindowLong(_hwnd, GWL_STYLE, _style); } void Control::SetClass(wchar_t * name) { if(!name) return; if(_class != NULL) { delete [] _class; _class = NULL; } _class = new wchar_t[wcslen(name) + 1]; wmemset(_class, '\0', wcslen(name) + 1); wmemcpy(_class, name, wcslen(name)); if(_hwnd) throw std::runtime_error("Can't change the class of a control after it has been created!"); } void Control::SetName(wchar_t * name) { if(!name) return; if(_name != NULL) { delete [] _name; _name = NULL; } _name = new wchar_t[wcslen(name) + 1]; wmemset(_name, '\0', wcslen(name) + 1); wmemcpy(_name, name, wcslen(name)); if(_hwnd) ::SendMessageW(_hwnd, WM_SETTEXT, NULL, reinterpret_cast<LPARAM>(_name)); } void Control::SetClass(char * name) { if(!name) return; if(_class != NULL) { delete [] _class; _class = NULL; } wchar_t * uni = NULL; AnsiToUnicode(name, &uni); _class = new wchar_t[wcslen(uni) + 1]; wmemset(_class, '\0', wcslen(uni) + 1); wmemcpy(_class, uni, wcslen(uni)); CoTaskMemFree(uni); if(_hwnd) throw std::runtime_error("Can't change the class of a control after it has been created!"); } void Control::SetName(char * name) { if(!name) return; if(_name != NULL) { delete [] _name; _name = NULL; } wchar_t * uni = NULL; AnsiToUnicode(name, &uni); _name = new wchar_t[wcslen(uni) + 1]; wmemset(_name, '\0', wcslen(uni) + 1); wmemcpy(_name, uni, wcslen(uni)); CoTaskMemFree(uni); if(_hwnd) ::SendMessageW(_hwnd, WM_SETTEXT, NULL, reinterpret_cast<LPARAM>(_name)); } void Control::SetX(double x) { _x = x; if(_hwnd) ::MoveWindow(_hwnd, _x, _y, _width, _height, TRUE); } void Control::SetY(double y) { _y = y; if(_hwnd) ::MoveWindow(_hwnd, _x, _y, _width, _height, TRUE); } void Control::SetHeight(double height) { _height = height; if(_hwnd) ::MoveWindow(_hwnd, _x, _y, _width, _height, TRUE); } void Control::SetWidth(double width) { _width = width; if(_hwnd) ::MoveWindow(_hwnd, _x, _y, _width, _height, TRUE); } void Control::Focus() { if(_hwnd && !_ctl_parent) { ::SetForegroundWindow(_hwnd); } else if(_hwnd && _ctl_parent) { ::SetForegroundWindow(_ctl_parent->_hwnd); ::SetFocus(_hwnd); } } void Control::SetMenu(unsigned int hMenu) { if(hMenu != NULL && _hinst != NULL) { _menu = ::LoadMenu(_hinst, MAKEINTRESOURCE(hMenu)); if(_hwnd != NULL) { ::SetMenu(_hwnd, _menu); } } } void Control::SetMenu(HMENU hMenu) { if(hMenu != NULL && _hwnd != NULL) { ::SetMenu(_hwnd, _menu); } } void Control::SetBrush(HBRUSH hBrush) { _brush = hBrush; if(_hwnd) throw std::runtime_error("Cannot modify the brush at runtime."); } void Control::SetVScroll(bool VScroll) { _vscroll = VScroll; if(_hwnd) throw std::runtime_error("Cannot set VScroll at runtime."); } void Control::SetHScroll(bool HScroll) { _hscroll = HScroll; if(_hwnd) throw std::runtime_error("Cannot set HScroll at runtime."); } void Control::SetIcon(HICON hIcon) { _icon = hIcon; if(_hwnd) ::SendMessage(_hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(hIcon)); } void Control::Destroy() { if(_hwnd) ::DestroyWindow(_hwnd); } void Control::SetAnchors() { if(!_ctl_parent) return; HWND hWnd = _ctl_parent->GetHWND(); RECT rect; GetClientRect(hWnd, &rect); double width = rect.right; double height = rect.bottom; if(_x != 0 && _y != 0) { _top_left.SetAnchor((_x / width), (_y / height)); } else if(_x == 0 && _y != 0) { _top_left.SetAnchor(0, (_y / height)); } else if(_x != 0 && _y == 0) { _top_left.SetAnchor((_x / width), 0); } else if(_x == 0 && _y == 0) { _top_left.SetAnchor(0, 0); } if((_x + _width) != 0 && (_y + _height) != 0) { _bottom_right.SetAnchor(((_x + _width) / width), ((_y + _height) / height)); } else if((_x + _width) == 0 && (_y + _height) != 0) { _bottom_right.SetAnchor(0, ((_y + _height) / height)); } else if((_x + _width) != 0 && (_y + _height) == 0) { _bottom_right.SetAnchor(((_x + _width) / width), 0); } else if((_x + _width) == 0 && (_y + _height) == 0) { _bottom_right.SetAnchor(0, 0); } } Any help would be greatly appreciated. Thanks. -- Lenox
  3. Lenox

    String To Function Pointer

    Alright, thanks for your help guys, I'll look around. ^_^
  4. Do you think that this would ever be possible? Example: Say I have a function Foo, and it takes one string, which would be the name of a function with (void) as a parameter, and no return type. I create a void function Bar(), so then I pass "Bar" to Foo, to effectively create: Foo( "Bar" ) Then, perhaps, Foo would some how turn "Bar" into a function pointer, and then call the function. Perhaps something like this? void Bar() { // Do Stuff; }; void Foo( std::string func ) { typedef void (*func)(void) thisFuncPtr; // Our function pointer. }; So...is something like that already done and I'm just overlooking it, or what?
  5. Thats another problem - I had set Windowed to false, but it still comes up in a window. This really confused me, but I decided to accept it for now. [EDIT] Well, now I fixed the menu bar thing ( Now it's just hidden, I specified SW_SHOWMAXIMIZED ). All bugs are fixed! Thanks.
  6. Quote:Original post by S1CA1) Make sure you're pumping window messages (PeekMessage/GetMessage/DispatchMessage) when you get them - and in the same thread as your window. Process them in a timely manner if you want your UI to update in a timely manner. 2) Also ensure that any window messages you recieve which your application doesn't process get passed on to DefWindowProc(). 3) Call UpdateWindow() immediately after calling ShowWindow(), this will send paint messages to the window so that it'll re-paint using the black brush set in your window class (which is also why points 1 & 2 are important - if you don't handle WM_PAINT but also don't pass it on, the window won't paint, and if you don't pump messages, you won't recieve the message in the first place [shortly before Windows flags your app as "Not Responding"]). 4) Of course, for the DirectX part off your application: - what you see is what you Present(), remember to present what's been rendered. - you should Clear() before you render; including the Z buffer if you've enabled depth/stencil testing. Thank you for your help, the problem was that I was never actually calling ShowWindow, for one reason: From past experiences, I never HAD to use ShowWindow or UpdateWindow, Direct3D would always ( seem ) to take care of that for me. [EDIT] Well, now that I look again, there's still the problem with the start bar, it only shows a little bit of the name if I don't minimize or anything.
  7. Hey there, Lenox here. I made this ( very ) simple application that uses Direct3D to...well, pop up a black window. The problem is this: When I start up the application, the window does popup but the background is invisible and some of the name in the start bar is shown ( See Figure 1 ). I can fix the problem by minimizing it. ( The window should look as it does in Figure 2 ) Here's some code to go along with all of this. Direct3D.Cpp HRESULT Direct3D::Go() { pD3D9 = Direct3DCreate9( D3D_SDK_VERSION ); if( !pD3D9 ) { throw std::runtime_error( "Failed to initialize Direct3D." ); return E_FAIL; } D3DDISPLAYMODE d3ddm; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( D3DPRESENT_PARAMETERS ) ); pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); d3dpp.hDeviceWindow = GetInfo()->_hwnd; d3dpp.BackBufferWidth = GetInfo()->_width; d3dpp.BackBufferHeight = GetInfo()->_height; d3dpp.Windowed = GetInfo()->_windowed; d3dpp.BackBufferFormat = d3ddm.Format; d3dpp.BackBufferCount = 1; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; if( pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dpp, &pD3DDevice9 ) != D3D_OK ) { iLogger.Write( "status", "Failed to create the Direct3D Device" ); throw std::runtime_error( "Failed to create the device." ); return E_FAIL; }; iLogger.Write( "status","Direct3D Initialized" ); return S_OK; }; Window.hpp inline HRESULT Register( WindowInfo * x) { WNDCLASSEX _class; _class.cbSize = sizeof( WNDCLASSEX ); _class.style = CS_HREDRAW | CS_VREDRAW; _class.lpfnWndProc = x->_wndProc; _class.cbClsExtra = NULL; _class.cbWndExtra = NULL; _class.hInstance = x->_hinstance; _class.hIcon = LoadIcon( NULL, IDI_APPLICATION ); _class.hCursor = LoadCursor( NULL, IDC_ARROW ); _class.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); _class.lpszMenuName = NULL; _class.lpszClassName = x->_winType.c_str(); _class.hIconSm = LoadIcon( NULL, IDI_WINLOGO ); if( !RegisterClassEx( &_class ) ) { iLogger.Write( "status","Failed to register the window class." ); throw std::runtime_error( "Failed to register the window class." ); return E_FAIL; }; iLogger.Write( "status","Window class registered successfully." ); return Create( _class , x); }; HRESULT Create( WNDCLASSEX _class , WindowInfo *x) { HWND hWnd = NULL; hWnd = CreateWindow( _class.lpszClassName, x->_name.c_str(), x->_style, CW_USEDEFAULT, x->_y, x->_width, x->_height, NULL, NULL, x->_hinstance, NULL ); if( !hWnd ) { iLogger.Write( "status","Failed to create the window." ); throw std::runtime_error( "Failed to create the window." ); return E_FAIL; }; iLogger.Write( "status","Window created successfully." ); _init->PassHWND( hWnd ); return _init->Go(); }; Any help would be appreciated, Thank you. [Edited by - Lenox on November 20, 2005 2:28:03 PM]
  8. Lenox

    Logfiles and String Tables

    I have an xml file that I've structured like this: First we have our <log> block. Then follows our <header> block which contains some info about that log file. Then we have our <entry> blocks, they have special attributes: id and type. The ID is a number given to it by the engine that identifies it, so that we know it goes in order. The type tells what info the entry will give us. So, <log> <header> </header> <entry id="0" type="status"> </entry> </log> That would be an example of one of my log files. I'm looking into parsing that with TinyXML, so that I can organize it and make it even easier to read.
  9. Lenox

    PeekMessage returning NULL

    Oh, excuse me, I forgot to show the code for my Window.hpp, which contains the definition for the ctor I use. ( I really should take that out of the source file nad just define it in the header. ) Window.hpp class IWindow { protected: private: bool _windowed; ///< Whether or not the window is in fullscreen int _width; ///< Width int _height; ///< Height bool _suspended; ///< Whether or not the window is suspended. HINSTANCE _hinstance; ///< Handle to the instance. const char * _name; ///< Window Name const char * _winType; ///< Window Type WNDPROC _wndProc; ///< Window Proc int _x; ///< Horizontal Position. int _y; ///< Vertical Posiiton. int _style; ///< Style HWND _hwnd; ///< Handle to the window. public: /// \return True if this window is windowed, false is not. inline bool getWindowed() { return _windowed; }; /// \return The handle to the window. inline HWND & getHandle() { return _hwnd; }; /// \return Window Width. inline int getWidth() { return _width; }; /// \return Window Height inline int getHeight() { return _height; }; /// Constructor IWindow( const char *name, const char *className , HINSTANCE hInst, int x, int y, int width, int height, bool bWindowed, WNDPROC wndProc, int Style ) : _wndProc( wndProc ), _width( width ), _height( height ), _hinstance( hInst ), _windowed( bWindowed ), _name( name ), _winType( className ) , _x( x ), _y( y ), _style( Style ), _hwnd( NULL ) { Register(); }; IWindow(); /// Destructor ~IWindow() { iLogger.Write( "status","Window Destroyed Successfully." ); }; /// A check to see if the class is still valid. /// \return false if _hwnd is valid, true if _hwnd is invalid. inline bool operator !() { return !(_hwnd); }; /// Create the window /// \return void void Create( WNDCLASSEX _class ); /// Register the window /// \return void void Register(); /// Set the handle instance inline void SetInstance( HINSTANCE hInst ) { _hinstance = hInst; }; /// Add a timer inline void AddWndTimer( const int Name, int Interval, TIMERPROC tCallback ) { SetTimer( _hwnd, // Handle to the window Name, // Timer name Interval, // 1 second intervals tCallback ); // No callback }; }; I placed a breakpoint in my Register function to make sure _wndProc was non-null, and sure enough, it's pointing at the proper function.
  10. For some odd reason, PeekMessage is returning NULL -every- time. Here's some code for all of this.. Kernel.cpp BOOL Kernel::Run() { // AddWndTimer( FPS_TIMER, 1000, NULL ); DebugBreak(); // It breaks here while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { if( msg.message == WM_QUIT ) { SetExitCode( msg.wParam ); return FALSE; }; DebugBreak(); TranslateMessage( &msg ); DispatchMessage( &msg ); }; DebugBreak(); // And it breaks here. EVERY TIME. return TRUE; }; Kernel::Kernel( HINSTANCE hInst ) : IWindow( "Audeuro Adakitsa", "#32769", hInst, 0,0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ), false, &WindowProc, WS_POPUP | WS_VISIBLE ) { Init( GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ), getHandle(), getWindowed() ); }; Kernel::~Kernel() { iLogger.Write( "status", "Engine Ended." ); }; Kernel.hpp class Kernel : public Direct3D , public IWindow , public CThread { protected: static int HandleKeyboardInput( WPARAM wParam ); private: WPARAM _exitcode; MSG msg; COLORREF m_ColorKey; public: static int pFrames; Kernel( HINSTANCE hInst ); ~Kernel(); WPARAM GameLoop(); static LRESULT CALLBACK WindowProc( HWND , UINT, WPARAM, LPARAM ); static void PrintFPS(); inline WPARAM GetExitCode() { return _exitcode; }; inline void SetExitCode( WPARAM exitCode ) { _exitcode = exitCode; }; BOOL Run(); }; And finally..Window.cpp IWindow::IWindow() { }; void IWindow::Register() { WNDCLASSEX _class; _class.cbSize = sizeof( WNDCLASSEX ); _class.style = CS_HREDRAW | CS_VREDRAW; _class.lpfnWndProc = _wndProc; _class.cbClsExtra = NULL; _class.cbWndExtra = NULL; _class.hInstance = _hinstance; _class.hIcon = LoadIcon( NULL, IDI_APPLICATION ); _class.hCursor = LoadCursor( NULL, IDC_ARROW ); _class.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); _class.lpszMenuName = NULL; _class.lpszClassName = _winType; _class.hIconSm = LoadIcon( NULL, IDI_WINLOGO ); if( !RegisterClassEx( &_class ) ) { iLogger.Write( "status","Failed to register the window class." ); throw std::runtime_error( "Failed to register the window class." ); }; iLogger.Write( "status","Window class registered successfully." ); Create( _class ); }; void IWindow::Create( WNDCLASSEX _class ) { _hwnd = CreateWindow( _class.lpszClassName, _name, _style, CW_USEDEFAULT, _y, _width, _height, NULL, NULL, _hinstance, NULL ); if( !_hwnd ) { iLogger.Write( "status","Failed to create the window." ); throw std::runtime_error( "Failed to create the window." ); }; iLogger.Write( "status","Window created successfully." ); }; I'm not exactly sure why it won't work right, it just never hits the breakpoint in my loop.
  11. Thanks, I just went back and realized that the class needs serious refactoring, so I've changed my method of doing it - I now use templates to decide what type of class it is then make a copy of "this" to use, then if I really feel like passing any type of information through my Create() function, I'll pass it as void*.
  12. Hey, I have a problem. Well, I recently created my own thread class ( It may not look original, but trust me, I spent about 20 minutes researching the thread functions ( _beginthreadex, _endthreadex, ResumeThread, and SuspendThread..those types of things ) ) and now, I'm getting access violations when calling functions that are virtual but undefined in the base class. Thread.hpp #ifndef THREAD_HPP #define THREAD_HPP #include "stdafx.hpp" class Mutex { protected: private: const char * _name; HANDLE _handle; public: Mutex( const char* Name ) : _name( Name ) { _handle = CreateMutex( NULL, true, _name ); assert( _handle != NULL ); } ~Mutex() { ReleaseMutex( _handle ); }; }; class Thread { protected: // Operations inline void Resume() { ResumeThread( GetCurrentThread() ); }; inline void Suspend() { SuspendThread( GetCurrentThread() ); }; inline void End() { _endthreadex( _threadId ); delete _mutex; }; static unsigned int _stdcall EntryPoint( void* pThis ); virtual void Setup()=0; virtual void Execute( void *Arg )=0; void Run(); private: unsigned int _threadId; void * _Arg; Mutex * _mutex; public: int Create( void* Arg ); void Delete(){ End(); }; Thread(); virtual ~Thread() { if( !_mutex ) { return; } else { End(); }; }; }; #endif Thread.cpp #include "Thread.hpp" Thread::Thread() {}; int Thread::Create( void* arg ) { _Arg = arg; int cCode; _mutex = new Mutex(NULL); cCode = static_cast<int>(_beginthreadex(NULL, NULL, &Thread::EntryPoint, _Arg, NULL, &_threadId )); return cCode; }; unsigned int _stdcall Thread::EntryPoint( void *pThis ) { Thread * pThread = static_cast< Thread* > ( pThis ); pThread->Setup(); pThread->Execute( pThread->_Arg ); return 1; }; I put that to work with this: Message Pump.hpp #ifndef MESSAGEPUMP_HPP #define MESSAGEPUMP_HPP #include "Thread.hpp" #include "stdafx.hpp" #include "Kernel.hpp" class MessagePump : public Thread { protected: private: MSG msg; int _exit; public: void Setup() { _exit = 0; }; void Execute( void *arg ) { do { while( PeekMessage( &msg, static_cast<HWND>(arg), 0, 0, PM_REMOVE ) ) { if( msg.message == WM_QUIT ) { Inst->SetExitCode(msg.wParam); _exit = 1; break; }; }; } while( !_exit ); }; }; #endif And then created an instance of that class and called Create(), calling Delete() at program exit. Any help and suggestions on improvements for my Thread class, please do NOT hesitate to post. SIDE-NOTE: I was not intending for mutex to work. Thanks for any help in advance, -Lenox
  13. Hey there, Lenox here. I'm have a problem with D3D and CreateDevice- for some reason, it's returning D3DERR_NOTAVAILABLE and with me being new to this whole Direct3D scene, I'm not sure how to fix this. Here's how I'm initializing it all: HRESULT Direct3D::Init() { D3DDISPLAYMODE D3DDM; pD3D9 = Direct3DCreate9( D3D_SDK_VERSION ); if( !pD3D9 ) { throw std::runtime_error( "Failed to create Direct3D." ); return E_FAIL; } pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &D3DDM ); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( d3dpp ) ); d3dpp.BackBufferWidth = GetSystemMetrics( SM_CXSCREEN ); d3dpp.BackBufferHeight = GetSystemMetrics( SM_CYSCREEN ); d3dpp.BackBufferCount = 1; d3dpp.BackBufferFormat = D3DDM.Format; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.Windowed = _windowed; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Make damn sure everything is good. assert( _hwnd ); // Window Handle HRESULT CD = pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, _hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3DDevice9 ); if( FAILED( CD ) ) { switch( CD ) { case D3DERR_DEVICELOST: { throw std::runtime_error( "The device has been lost, but cannot be reset." ); }; case D3DERR_INVALIDCALL: { throw std::runtime_error( "Invalid Call: Create" ); }; case D3DERR_NOTAVAILABLE: { throw std::runtime_error( "The device does not support the queried technique." ); }; case D3DERR_OUTOFVIDEOMEMORY: { throw std::runtime_error( "Direct3D does not have enough memory to support this operation ."); }; default: { throw std::runtime_error( "Failed call to CreateDevice." ); }; }; return E_FAIL; }; return S_OK; }; Any help would be appreciated, thanks. [edit] sorry, forgot source tags. [Edited by - Lenox on October 18, 2005 4:58:14 PM]
  14. Hello, Lenox here. I was idling in IRC today and I saw someone mention this idea they were thinking about: Creating AI that starts out without any knowledge of their environment, then as they go they learn more about their surroundings and become more capable of interacting with them. Well, this made me ask myself ( and this is also what I'm currently asking you ), "How could I go about doing this?" So, to sum it all up: * I'd like to make some AI that can learn about and interact with it's environment, so does anyone have any good resources on this?
  15. Hey, I was wondering if I could get a few people to perhaps drop by this thread and criticize my memory "tracking" code? I think that improvements can be made and security can be increased, so any criticism IS welcome, constructive or not. Memory_Tracker.hpp #ifndef MEMTRACKER_HPP #define MEMTRACKER_HPP #ifdef _DEBUG extern std::ofstream memLog; #include "Allocations.hpp" struct xAllocStruct { const char *File; int Line; const char *Function; void *P; }; typedef stdext::hash_map< void *,xAllocStruct *, stdext::hash_compare< void*, std::less< void*> >, xMallocAllocator< std::pair< const void*, xAllocStruct* > > > xMallocMap; extern xMallocMap xMap; extern int ID; inline void Write_Memory( const char *File, int Line, void *Ptr, const char *Func) { memLog << "\t<entry id=\"" << ID++ << "\">\n"; memLog << "\t\t<file>" << File << "</file>\n"; memLog << "\t\t<line>" << Line << "</line>\n"; memLog << "\t\t<pointer>" << Ptr << "</pointer>\n"; memLog << "\t\t<function>" << Func << "</function>\n"; memLog << "\t</entry>\n"; }; inline void * __cdecl operator new( size_t size, const char *File, int Line, const char *Function ) { void *p = malloc( size ); xAllocStruct *aStruct = (xAllocStruct*)malloc( sizeof( xAllocStruct ) ); aStruct->File = File; aStruct->Line = Line; aStruct->Function = Function; aStruct->P = p; xMap[ p ] = aStruct; return p; }; inline void __cdecl operator delete( void *Ptr ) { // for( xMallocMap::iterator Iter = xMap.begin(); Iter != xMap.end(); Iter++ ) // { // Thanks to snk_kid for suggesting find xMallocMap::iterator Iter = xMap.find( Ptr ); if( Iter != xMap.end() ) { xAllocStruct *aStruct = Iter->second; if( aStruct->P == Ptr ) { free( Ptr ); free( aStruct ); xMap.erase( Iter ); break; }; }; }; #define new new( __FILE__,__LINE__, __FUNCTION__ ) inline void CleanUp() { if( !xMap.empty() ) { for( xMallocMap::iterator Iter = xMap.begin(); Iter != xMap.end(); Iter++ ) { xAllocStruct *Struct = Iter->second; Write_Memory( Struct->File, Struct->Line, Struct->P, Struct->Function); }; xMap.clear(); }; memLog << "</log>\n"; memLog.close(); }; #endif #endif Allocations.hpp #ifndef ALLOCATIONS_HPP #define ALLOCATIONS_HPP #include "StdAfx.hpp" template< typename T > class xMallocAllocator { public: template< typename U > struct rebind { typedef xMallocAllocator< U > other; }; public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; public: template< typename U > xMallocAllocator( const xMallocAllocator< U >& ) {}; xMallocAllocator() {}; xMallocAllocator( const xMallocAllocator& ) {}; public: pointer allocate( size_type n, const void *unused = 0 ) { T *x = (T*)malloc(n * sizeof( T )); return x; }; pointer address( reference x ) const { return &x; }; public: const_pointer address( const_reference x ) const { return &x; }; public: void deallocate( void* p, size_type ) { if( p ) { free( p ); }; }; void construct( pointer p, const_reference val ) { ::new( static_cast< T* >( p ) ) T( val ); }; void destroy( pointer p ){ p->~T(); }; public: template< typename U > xMallocAllocator& operator=( const xMallocAllocator< U >& ) { return *this; }; xMallocAllocator< T >& operator=( const xMallocAllocator& ) { return *this; }; inline bool operator==( const xMallocAllocator< T >& ) { return true; }; public: size_type max_size() const { return size_t( -1 ); }; }; #endif It works nice for me, but I'm pretty sure you guys will find things that I can change or add to make it safer, or perhaps you have suggestions to things that I can fine-tune for optimizations or for more features. [Edited by - Lenox on October 15, 2005 1:48:58 PM]
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!