|
Rick York wrote: I thought there must be an instance of an object to use a pointer to one.
If the function which is called do not access any members of the class, then it is "safe". But of cours it is absolutely bad practice.
Rick York wrote: Even with a static member that is not the best syntax to use though.
This, on the other hand is perfectly acceptable.
I should take a coffee before answering questions on CP . This is not that acceptable, since the static function should accessed this way: ClassName::MethodName()
|
|
|
|
|
Cedric Moonen wrote: This, on the other hand is perfectly acceptable.
However, the wise developer would use the classname::method syntax.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
I think I was not awake when I replied, I really thought he was talking about accessing the static function using the classname::method syntax. Pff, ok, I'll fetch a coffee now.
|
|
|
|
|
I can barely reach my workstation, without caffein.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
With the risk of being wordy...
This piece of code should illustrate things.
class Z
{
public:
int g;
void out(){printf("addr %p\n", this);}
void outg(){printf("addr %p g=%d\n", this, g);}
};
Z *pz1, *pz2=0, *pz3=(Z*)0xdeadbabe, *pz4, z;
void main()
{
pz1->out();
pz2->out();
pz3->out();
pz4->out();
z.g=100;
pz1=&z;
pz1->outg();
pz2->outg();
pz3->outg();
pz4->outg();
}
As you can see, pz1 to pz4 are either not initialized or are initialized to "wrong" values. However, lines 1 to 4 execute happily, even though you dereferance using these wrong pointers. Thats because you aren't actually touching the member variable at all.
Now, look at what happens next. At line 6, pz1 is initiated to a valid address and hence outg() doesn't complain. Why should it complain you may ask. I'll tell you.
Open the disassembly window and step into the function call at line 8. There you'll find that the control actually steps into the function, even when derefeneced using a wrong pointer! Thats because one line of C/C++ translates into many many lines of assembler. As you step past each assembler instruction, you'll encounter this instruction
mov ecx, dword ptr [eax]
and that is where you get the tantrum.
In this line, the member variable 'g' is attempted to be accessed. EAX really holds the address of the object but because 'g' is the first member, the address coincide. And the complaint is valid as you cannot CANNOT SHOULD NOT access data from uninitialized memory.
EDIT: I forgot to mention that you have to turn off "incremental linking". It doesn't matter much except that if its on you might get confused and/or distracted by the " @ILT+nnn " that you'll encounter. An oh, its MSVC6.0
...byte till it megahertz...
modified on Thursday, August 5, 2010 3:33 AM
|
|
|
|
|
|
ccpptrain wrote: ->Whether this method of using uninitialized pointer is acceptable in any condition?
It is acceptable as long as you are careful, as you promised absolutely no data members. With this condition, you initialize or don't initialize or simply call using 0 (zero) pointer, it is acceptable.
ccpptrain wrote: ->Will this work on different platforms?
It is same for all platforms.
ccpptrain wrote: ->Any pitfalls?
One more promise: don't delete the pObj.
ccpptrain wrote: ->Your Valuable suggestions.
Don't do like this. You never know when you are going to add member variables and access them.
|
|
|
|
|
my app crashed, i suspect some of const class members are not initialized.
actually, compiler can not detect uninitialized const pointers, i.e.
const CWnd*pc;
as class member, but there is no error if forgot to initialize it.
why? - I don't think that default value of NULL is good reason to allow code above be compiled.
so I did a test inside a function, which shows no error:
const CWnd*pc0=0;
CWnd*pc1=(CWnd*)100;
pc0=pc1;
for other types of data, such as int, above code can not be compiled.
Any idea to solve the problem to make sure const pointer must be inilialized?
|
|
|
|
|
const CWnd*pc; here pc is not a constant pointer. It is a pointer to const CWnd object.
Constant pointer is declared as follows: CWnd* const pc;
|
|
|
|
|
Most compilers can detect use of uninitialised pointers. Try cranking the warning level up and flagging warnings as errors (/W4 /WX on VC++ and gcc IIRC).
If you want to make sure that pointers are initialised before use there is a solution - don't use pointers. There's really no reason to use raw pointers these days (apart from compatibility with code written in C). Pointers have three uses and there's a better solution for all of them:
- marking ownership - instead use a smart pointer, even std::auto_ptr is usable with a few caveats
- iteration - use containers and use iterators from the containers
- referring to other objects - use references if the object can't be rebound, a smart pointer if it can.
Now onto the const bit... You've read the type wrong. What you've got isn't a "constant pointer" but a "pointer to a constant object". C and C++ have slightly strange declarators in that you don't read them left to right but identifier outwards in precedence order.
Cheers,
Ash
|
|
|
|
|
Hello folks!
I used GlobalMemoryStatusEx[^] to get memory information. As the subject suggests, i am looking for the available physical memory my process may allocate, however, the ullAvailPhys member of MEMORYSTATUSEX[^] shows all the available memory bytes, not only the bytes allocatable by my process. So you understand, windows has a 2Gb (i know this can be increased to 3Gb but that's of no relevance right now) limit per process. So if my computer has 3Gb memory, my process allocates 1.5Gb, then i check the free memory size, i get 1.5G, but if i try to allocate that 1.5G, it will fail since only 0.5G is available to my process. I might be wrong, i am not sure, so please correct me if i am.
So i figured, if i take the smaller value of ullAvailPhys and ullAvailVirtual , this should give me the available physical mem for my process, but this is really a guess. So...can someone tell me how to do this correctly, or if this way is reliable?
Thanks for any info in advance.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Which API did you call to allocate memory?
|
|
|
|
|
Well, the "default" implementation of new and malloc are mostly used for memory allocation as far as i know (what memory allocators 3rd party codes and windows API calls use is beyond me).
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Default implementation of new of vc is malloc and malloc calls VirtualAlloc .
I checked how much memory's can be allocated on my pc with XP SP3.
Available Phys. Memory: 1.7GB (from task manager)
Available Virtual Memory: 2.0GB (from GlobalMemoryStatusEx )
My program allocated: 1.5GB (by VirtualAlloc or malloc )
My program's Total Virtual Size: 1.5GB (from task manager)
In general, total virtual memory space 2GB is sum of program own code size, some resources and other crt dll space size. So in this case, my program's size without heap should be around 500MB. (I think this strange.)
I guess some other programs (like a anti virus program or so) or some Windows settings affected to this situation.
|
|
|
|
|
Thanks but i don't see how this answers my question...please clearify and sorry for my ignorance.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I have a CDialog class with controls (e.g. CMySlider:public CSliderCtrl).
If I right click on the control area, the layered popup window is created, moved, and displayed.
Code is:
in MySlider::OnRButtonDown
bRes = CreateEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST|WS_EX_NOACTIVATE,
AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS),
NULL,
WS_POPUP|WS_VISIBLE,
0, 0, 0, 0,
NULL,
NULL,
0);
...........
if (bRes)
{
CRect tipWndRect = SetTipWndRects(...);
.........
SetLayeredWindowAttributes(RGB(...)), 0, LWA_COLORKEY);
MoveWindow(&tipWndRect, FALSE); // Tip is not visible because init. rect is empty
..........
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOERASE);
GetOwner()->SetFocus();
}
All is working. Problem is that the popup window immediately gets focus and before the control acquires
focus back, I see flicker: the dialog box loses focus, its non-client area changes colors, and all returnes to th state when popup is visible and the control keeps focus.
How can I show the popup in block the transfer of focus?
I tried OnSetFocus, OnKillFocus, but it seems that these functions are called after events.
geoyar
|
|
|
|
|
Don't create your window with WS_VISIBLE, show it afterwards with ShowWindow(SW_SHOWNOACTIVATE)[^] or SW_SHOWNA, also, i believe MoveWindow, next to moving the window, will also show and activate it for some reason, instead of that, use SetWindowPos[^] instead. You can also use SetWindowPos with SWP_SHOWWINDOW | SWP_NOACTIVATE to also show the window without activating it (so no need for a separate call to ShowWindow)
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Thank for reply.
In my opinion, WS_VISIBLE does not matter at the point of window creation, beause I pass the empty rect(CRect(0, 0, 0, 0)) to CreateEx. Anyway, I tried it without WS_VISIBLE with the same results.
When you use MoveWindow(..., bRedraw = FALSE) the window is not visible, and the focus is not transferred. ShowWnindow(SW_NOACTIVATE) does not work because it post the WM_PAINT as a last message to be processed: I tried it and no immediate reaction was visible. Besides, it seems that NO_ACTIVATE is about user input, not about focus.
For me it seems that the culprit is WM_EX_TOPMOST. Seems that the topmost window get the focus always. WM_EX_LAYERED|WM_EX_TRANSPARENT redirect user input to underlayng windows, but not the focus.
So my problem is about preventing the transfer of the focus when the popup window is created and displayed from whithin another window.
geoyar
|
|
|
|
|
I did a little test project:
HWND hwnd = ::CreateWindowEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_NOACTIVATE,
AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS),
NULL,
WS_POPUP|WS_DLGFRAME,
0, 0, 100, 100,
NULL,
NULL,
GetModuleHandle(NULL),
NULL);
::SetLayeredWindowAttributes(hwnd, RGB(10, 20, 30), 255, LWA_COLORKEY);
::SetWindowPos(hwnd, CWnd::wndTopMost, 100, 100, 200, 50, SWP_SHOWWINDOW | SWP_NOACTIVATE);
it seems to be working for me, i get a topmost, layered window that does not grab the focus.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I got the problem with focus when I show the window on right click on the control in active dialog box. The window is anchored to some point inside the control and the window rect is less than the rect of the dialog box. If I do not set WS_EX_TOPMOST, the window is under the dialog box, and is not visible. If the ex style is set to WS_EX_TOPMOST, I have my problem. If the window is set outside the dialog box rectangle, it is wisible without WS_EX_TOPMOST. I think it is because the dialog stays as a topmost window.
What is interesting, if I would set this window as a modeless dialog box, there is no problem with flicker. I did not check the situation with focus yet.
I think Microsoft does some trick with the dialog box and its controls. When we are moving from contorol to control we see no flicker.
geoyar
|
|
|
|
|
I used a dialog based app to test what i wrote in my previous post, the window stayed above the dialog as it should, did you try the way i did? WS_EX_TOPMOST isn't specified when creating the window but SetWindowPos will make a topmost window. I'm not sure what you mean by flicker, when your new window gets the focus, it becomes the active window of your application, this will make your dialog repaint its border/caption to show it is no longer active, also the focus rect will be removed from whereever it was on the dialog. Then when you set the focus back, it will make your dialog the active window again, causing it to repaint its border and title again, along with the focus rect (if there is one), i guess that's what you mean, no? If you tab around the dialog's controls, this does not change the active window, thus, no border/title repaints.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Yes, you are right. It is about repainting the dialog border.
I tried SetWindowPos with SWP_NOACTIVATE|SWP_SHOWWINDOW and the first parameter as &wndTopMost and &wndTop. With &wndTop the window is invisible, with &wndTopMost it is visible. On both occasions the dialog window loses focus and the frame is repainted.
It happens no matter what the first parameter of the SetWindowPos you passed.
geoyar
|
|
|
|
|
How does your code look like now?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Sorry, I have deleted all SetWindowPos from my code.
I remember that in my other app I used a modeless dialog box with CStatic in it over the modal dialog box. I have no problem with focus, placement and visibilty of this box.
So I created a modeless dialog box CTipDlg m_tipDlg and added to OnRButtonClick:
OnRButtonDown(UINT nFlags, CPoint point)
{
m_tipDlg.Create(IDD_TIPDLG, this);
m_tipDlg.SetLayeredWindowAttributes(RGB(10, 10, 10), 0, LWA_COLORKEY);
m_tipDlg.ShowWindow(SW_SHOW);
.....................................................................
}
Now I see two dialogs, one modal, one modeless(layered, transparent and not topmost), with two active frames. The focus stays on control I have clicked.
It is the test of concept for now. It might not work for me at the end. But focus behaves as I wanted.
Of course it is overkill, because all I need is a visible window.
Of course I will look in CDialog MFC code.
Any help will greatly appreciated.
geoyar
|
|
|
|
|
I'd like to help, but i don't see how...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|