Have just started with some Windows programming, and i´m working on a window class. I thougth that it was a good idea to have a static LPWSTR that I could use when I create different windows in my program. Doubt that I will need more when I move on to direct3D but I still want to have the feature, and it seems like it can be good to learn how Windows deals with a program that has multiple windows.
Know I dont really know how Windows uses the WINDCLASS(EX) classname, if there are any advantadges of having more than one class, in that case please tell me.
Well lets talk about my problem. I declare the static LPWSTR (Correct me if i´m wrong but this is a wchar_t*??) here:
class Window
{
public:
//other code removed
static LPWSTR windowClassName;
}
Then a set the variable before I create my first window:
Window::windowClassName = L"WindowClass";
Window window1 = Window(L"Engine Window1");
window1.initialize(hInstance, 100, 100, 1280, 720);
window1.showWindow(cmdShow);
But I get the unresolved externals error. This doesn´t make sense to me, so I can create a static variable in a class, make it public, but I can´t change it? What do I have to do to make this to work? Or is it just so simple that static members cant be set in a method? That I think would be really stuip since I can´t set it´s value during run-time. Can someone please explain this to me?
Related
I'm working on a SFML project that contains several different files and classes. The problem is : in every file, there is some drawing, and the sf::RenderWindow* defined in the main file seems to be out of scope here, therefore I can't link these drawing with the main window. I've tried to redefine sf::RenderWindow in every header files, and it doesn't work as well (a black screen appear and disappear promptly). The error was : Access violation reading location. But when I group everything in one file, things work well but it looks really messy.
I also found this question asked on another forum, and the answers were "using reference and external method", which is a bit vague to me. Any help on this linking problem would be appreciated :(
I think that answer meant something like:
void draw_in_class (sf::RenderWindow* window){
window->draw(...);
}
in class, and then you can use 'draw_in_class' in main:
#include"class.h"
... // Define sf::RenderWindow here
draw_in_class(&window);
I am experimenting with some fundamental Xlib stuff. I am creating a basic window and creating an OpenGL context for it.
I am trying to prevent the user from being able to resize or manually full screen the window. I added the code:
XSizeHints hints;
hints.min_width = hints.max_width = setup.w;
hints.min_height = hints.max_height = setup.h;
XSetWMNormalHints(dpy, win, &hints);
This worked at first. However after experimenting with it I have found that it mysteriously stops working sometimes. It is not a matter of unusual window managers or anything like that, I am using the default windows manager installed with Ubuntu. What causes it to change, strangly enough, is whether or not I include this line in main:
XWindowAttributes atts;
It does not matter where I put it. At the beginning, or inside a loop, or even after the return. As long as I put that somewhere in main the hints prevent resizing (just to be clear, any name for the variable works). It does not matter if I use it at all or not, it was initially there for a call to XGetWindowAttributes. I discovered the problem when I tried moving that into a separate function call. If I take it out, the window will have a full screen button and I will be able to shrink it. I have experimented with declaring the variable other places, such as in the struct where I contain the Window and GLXContext.
What is going on here? The way I see it I either have a very subtle and unusual bug coming from my virtual machine or something weird like that, or I have missed some obvious piece of information. Can anyone shed some light on this?
Well, I have no explanation for why declaring a XWindowAttributes instance in main was making it work, but I did figure out what was wrong with my code and I was able to make it behave as expected when I made the following changes:
Do not create XSizeHints directly as shown above. Create it as follows:
XSizeHints *hints = XAllocSizeHints();
Set flags in the object specifying which variables are used:
hints->flags = PMinSize|PMaxSize;
Use XSetWMNormalHints and XSetWMSizeHints:
XSetWMNormalHints(dpy, win, hints);
XSetWMSizeHints(dpy, win, hints, PMinSize|PMaxSize);
I also put a pointer to the hints in my struct containing data about the window. All together the code above became:
XSizeHints *hints = wind->hints = XAllocSizeHints();
hints->flags = PMinSize|PMaxSize;
hints->min_width = hints->max_width = setup.w;
hints->min_height = hints->max_height = setup.h;
XSetWMNormalHints(dpy, win, hints);
XSetWMSizeHints(dpy, win, hints, PMinSize|PMaxSize);
For those that came here:
1. Communicating with the Windows Manager
It's all about convention like said at 12.3 in the "Xlib Programming Manual VOL1". Some WM will completely ignore hints like max & min size, because eg they manage Windows as Tiled Windows. So, how YOUR Window Manager will get your choices is an issue.
2. Make things in the right order.
This will perhaps answer your question : "What is going on here?"
Most difficulties with X comes from the order you make things. I encountered the same trouble as yours, and solve it because I saw I didn't follow the right process.
Chapter 12.3.1 from the "Xlib Prog Manual" says:
'Once the client has created the windows, BUT BEFORE IT MAPS THEM, it must place properties to help WM manage them effectively'
In your case, it means you cannot use XSetWM* functions AFTER your window is mapped. Some properties will have an effect, some others not, and sometimes some will be overridden with bad values.
3. The right order. (AFAIK)
a. Set an Error Handler
b. Get a Display
c. Init your Context (here GLX) & get a Visual from it.
d. set Window Attributes (events mask, ...)
e. Create your Window
e. Set WM Properties (eg your sizehints, min/max size, class, title, ...)
e.1 always init pointers you need with XAlloc* when possible
e.2 use X11r4 XSetWMProperties that will put them all at once, avoid use of deprecated functions.
e.3 XFree your 'pointers'
f. Set the Wm Protocols you are interested in (WM_DELETE_WINDOW, ...)
g. set some others properties according to your needs (eg _NET_WM_PID, ...)
h. Finally, Map your Window
4. See what happens : use xprop
xprop will report how your window is known by your Windows Manager.
If your size hints were properly set, you will see some lines like:
WM_NORMAL_HINTS(WM_SIZE_HINTS):
user specified location: 550, 200
user specified size: 500 by 500
program specified minimum size: 500 by 500
program specified maximum size: 65535 by 65535
Hope it helps future users,
(PS: the previous answer TS#Oct 27 '14 at 15:26 has an error: XSetWMSizeHints expect an Atom as 3rd arg.).
I'm having a bit of trouble in my attempts to learn WXWidgets. I'm currently trying to work with file Dialogs, and I've got one opening just fine. But I run into trouble whenever I try to apply styles to the window. I get an undeclared identifier for whatever style I use.
My code is as follows (yes, I know, hello world app. I'm experimenting with all the things I need to learn to do before actually making a fully fledged app)
#include "wx/wx.h"
#include "wx/filedlg.h"
#include "HelloWorldApp.h"
IMPLEMENT_APP(HelloWorldApp)
bool HelloWorldApp::OnInit()
{
wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, _T("Hello wxWidgets World"));
wxFileDialog* OpenDialog = new wxFileDialog(frame, _("Choose a file to open"), wxEmptyString, wxEmptyString,
_("Image Files (*.jpg, *.png, *.gif, *.bmp)|*.jpg;*.png;*.gif;*.bmp|Sound Files (*.wav, *.mp3)|*.wav;*.mp3"),
wxFD_MULTIPLE);
frame->CenterOnScreen();
frame->Show(true);
OpenDialog->ShowModal();
SetTopWindow(frame);
return true;
}
It runs just fine without the "wxFD_MULTIPLE" argument. I'm using version 2.8.12 of wxWidgets.
Thanks for reading. I really appreciate any help or guidance anyone can give. Sorry if it's something really obvious I'm missing.
In very old wxWidgets versions (2.6), this style was known as wxMULTIPLE but wxFD_MULTIPLE is definitely available in any 2.8.x version. You should give the (beginning of) the errors you get to allow us to understand what is really going on.
Completely independently, your code is wrong because it contains a memory leak: the dialog must be destroyed as modal dialogs are exceptions to the usual rule that all windows should be allocated on the heap and can be allocated on the stack, i.e. used as simple local variables, see the example in the documentation. Looking at the "dialogs" sample code is also strongly recommended.
I'm very much a C++ newbie, so please bear with me.
This line of code which resides within a function:
CWnd* pWnd = CWnd::FindWindow("Shell_TrayWnd", "");
CWnd is coming up as "undefined". I know I need to define it in the global scope, but how? What header do I need to include to use this class? Project is MFC.
Using VS 2010.
Here's how to solve this problem independently.
First, Google for "cwnd"
Second, click the first link.
Third, read the page
Requirements
Header: afxwin.h
I'm writing a C++ MFC program on VS2008 and I'm getting this "Debug Assertion Error" when I first run the program sometimes. When I try to debug it, it takes me to this winhand.cpp file which is not part of the program I wrote so I'm not sure how to debug this.
It takes the error to this place in winhand.cpp
CObject* pTemp = LookupTemporary(h);
if (pTemp != NULL)
{
// temporary objects must have correct handle values
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ASSERT(ph[0] == h || ph[0] == NULL);
if (m_nHandles == 2)
ASSERT(ph[1] == h);
}
So why does this error happen? Why does it only happen sometimes (50% of the time)? How would I debug this?
I'll provide some code if is needed.
THANKS!
The code that is asserting is part of MFC's CHandleMap class. MFC deals with windows as CWnd objects, but Windows deals with them as HWND handles. the handle map allows MFC to 'convert' an HWND into a pointer to the MFC object representing that object.
What the assertion seems to be doing is checking that when a lookup of the handle finds an MFC object, that the MFC object also thinks it's wrapping the same handle.
If they're different, then you get the assertion.
So it would appear that something is corrupting the handle map or the MFC object for that handle or you're doing something incorrect that gets these 2 data structures out of sync.
Some things you might do to try to debug the problem is to determine:
what MFC object is being found in the lookup (that's what's being pointed to by pObject)
what the MFC object thinks it's wrapping (that's the handle ph[0] and/or ph[1] - I'm not sure why there can be 2 of them)
what the handle is for (that's h)
Do the handles look like handle values or do they look like garbage? Does pObject point to something that looks like an MFC object, or garbage? Do any of these these things seem related?
The answers to these questions may point to what you need to do next (maybe set a debug write breakpoint on the item that looks like it's trashed).
I got this same assertion few days ago, and after some google search,
I found the solution for my case here:
http://forums.codeguru.com/showthread.php?216770-What-would-cause-this-assertion
In my case, change to misused
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
dc->DeleteDC();
to
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
ReleaseDC(dc);
would fix it.
Look out for code along those lines (from memory from Stroustrup's book):
c1 = (t2+t3).c_str();
(in spirit, could be other commands and expressions of course).Temporary objects are destroyed after their enclosing full expression has been evaluated, or at least the standard allows them to be. That means that what you would like to allocate to c1 may, or may not, still be in memory where it can be assigned to c1. The compiler may alert you to this issue, and the issue may or may not arise depending on what exactly you assign and other circumstances (I am not compiler writer), which would also explain why you get this error message only sometimes.
So in your shoes, I'd scan my code for similar expressions and clean them up.
When the debugger breaks, head up the call stack to the first bit of your code (if there is any - hopefully there is!). Ideally it's as simple as something in your code calling a library function incorrectly, and the library is catching the error with an assert and alerting you to that. (I don't think anyone will be able to tell what's wrong from the library code, we need to see your code.)
Otherwise, you're in for some tricky debugging: you're doing something wrong with the library that is asserting (looks like MFC) so go back and review all your MFC code and make sure everything is correct and according to the documentation.
This looks suspiciously like an error I had this morning. Is this happening in OnIdle()?
I know this is a very old post, but hoping that someone may get a little help from my answer.
I also faced a similar issue recently because of my simple mistake, then I came across this post and got a hint from "pac"'s post.
What I found is that if I use DeleteDC() to release DC returned from GetWindowDC() or GetDC() I will get the above assertion in MFC frame once CPaintDC object instance goes out of scope.
CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);
You have to use DeleteDC() only in conjunction with CreateDC() API.
CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();
We had this problem when some of our project dlls were linking MFC as static library and some as shared library (check "Use of MFC" in Project settings)