Your struct contains one int and one pointer. If the second member said int* rather than void*, it would be exactly the same at run time - but at compile time, you would be warned if you tried to set .pBits to point to anything but an int. A void* can be set to point to anything.
Remember that in C, a pointer is nothing but a runtime address - no type info, no size info. An array name is a pointer to the start of a memory area; the index is an offset from this start address (the index value must be multiplied with the element size to get the offset in bytes). Runtime info knows only of the start address, and nothing of index limits and element type. In memory, a 1-element DWORD array is identical to a single DWORD variable. It looks like an array because you write code to address memory locations with some offset.
If you ask the compiler to address something pointed to by .pBits, the compiler doesn't know what to find there. Do you want to fetch a single byte from memory? Or a DWORD? Maybe .pBits really is a pointer to a struct, and you want to address a struct member at a given offset (i.e. member name). You have to tell the compiler how to interpret the pointer. This is because you haven't declared it as e.g. a DWORD* but as a void*.
In your example, the programmer tells the compiler: "Treat .pBits as a DWORD*, a pointer to a double word!" Here, the pointer itself is copied to another pointer, which can be used to access the DWORD pointed to - that is just as a convenient shorthand notation. Whether following code uses the typed DWORD* 'pbits' or '(DWORD*)lockedrect.pBits' makes no difference (at least not until you want to change one of the two pointers without changing the other one).
I can't tell why the void* was cast to a DWORD*. My guess, from the name D3DLOCKED_RECT, is that .pBits points to a 3D coordinate, like a 3 element array (or maybe even an array of 3D points). The code you quote wants to manipulate the 3 values as a single unit (e.g for more efficient moving/copying). Why is a void* used, instead of a typed pointer? Probably because the struct can be used with different resolutions (maybe that is what is indicated by the .pitch member?): In some applications, the coordinates are represented by three 16 bit values, in other applications by three 32 bit values. In low-resolution applications, it could even be three 8-bit values. You cast it to whatever coordinate size you use.
The quoted code makes it look as if the coordinates could be three 64 bit values. I very much doubt that any graphical system would use 64 bit coordinates (unless you make 3D model of the known universe...). So probably the use of DWORD is just for efficiency, doing moving/copying of as few operations as possible. That you could probably find out reading the rest of the code where you found this line.
What else would it be? In C, a pointer is an address, nothing more.
In other languages, such as C#, a reference is a the memory address of an object, comparable to a struct, containing not only the values of the members, but also a pointer to another struct, the class object, with pointers to the various member functions. Also in C#, an array reference is a pointer to a "struct" providing the index limit of the array. If you go back to good old Pascal. any string was headed by its length, any array by fields indicating its upper and lower index limits.
Not so with C. For reasons of space efficiency, space couldn't be wasted on such.
If you are programming in C++, a pointer to a class instance is similar: It points to a struct augmented by a reference to a class object (which may in turn have a pointer to a superclass object, with a pointer to an even superer object, and so on up to the very object class with all the attributes common to all objects. When you call a method for some bottom layer object, a search through this hierarchy is made to find method pointer. For virtual methods defined at a high/intermediate level, a pointer may be found at a lower level that where the virtual function is defined, and different (sub)class objects may provide different pointers to their respective implementations of the virtual functions. Static members at various levels of subclassing may be located in the class objects, common to all subclasses.
If you implement an array in C++ as class with an array member, you may of course store the maximum index as another class member and route all accesses through a member function verifying that no access violates the index limit. Roughly speaking, you could say that that's what happening in C# (or good old Pascal). But both for "performance" reasons (don't make any hard tests! You'd be disappointed!) and for backwards compatibility with classical C, an array name is nothing but a pointer (where you don't have to write the *), and a pointer, whether an array name or an explicit one (requiring a * for dereferencing) is nothing but a memory address.
Oldtimers remember the BASIC functions PEEK(address) and POKE(address) for reading/writing any value at 'address'. I am not sure that C compilers of today allow you to read/write the "array element" at 0[address]. In my student days they did. I certainly hope that they do not today... But then again, there is nothing in the C syntax rules prohibiting it, so why shouldn't you use it?
Additional comment: In the 1980s, there was an intense discussion about whether a data item should provide information about its type or not. If the data item knows whether it is 8, 16, 32 or 64 bits, float or integer, or whatever, it is represented once, not in every single instruction operating on it. The instruction code would not need different formats (/additional bits) to distinguish between e.g. integer add and floating add. So instructions - of which there are usually a lot more than values - would be a lot more compact, and the risk of interpreting a value in the wrong format significantly reduced.
An essential element of this approach was to store index limits once, with the array. If every array access makes is own check against array limits, the code/data for this check could grow significantly - way beyond what you are aware of when reading the code for a single access. It looks so tempting, 'I do it only when there is a risk of exceeding the array limits, but save the check when there is not'. I am 100% sure that the compiler (or even runtine system) is a lot more clever than you to make that decision. In languages with runtime array (/object) descriptors, it is possible. In C, or C++ in classical C usage pattern, it is quite difficult.
In languages with runtime array (/object) descriptors, it is possible. In C, or C++ in classical C usage pattern, it is quite difficult.
The proprietary language in which I worked for many years (designed in the late 1970s) had descriptors built in. The compiler knew the size of each array element, and a descriptor was a pointer to the beginning of the array (as in C++) and its size (number of elements). The compiler then generated code to perform bounds checking on an index at run-time.
If the size of the array was known at compile time, a descriptor wasn't needed; the compiler just did bounds checking against the fixed length. Descriptors were used for dynamically allocated arrays or to reference a subset ("slice") of a larger array.
Much more recently, C++ has added std::span[^] to the STL, which does the same thing.
It is a historic fact, now days on C99, C11 and beyond you might more correctly use a uintptr_t.
All you want really is the address but how big is that address it could be 16bits on a small micro controller, 32 bit on large CPU or 64bits on 64bit cpu. A void* pointer was usually big enough to ensure it had enough bits to point to any valid address on the CPU. So the size of a void* is completely compiler dependent. Back in the day there were also other features a void* could be cast to and from any other pointer without warning. The reason is obvious you want to be able to copy the address to a pointer of type and use normal c pointer functions.
Now move forward and look at a uintptr_t this is the C99 definition in stdint.h for portability under XSI-conformant systems
"an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer".
It acts like a void* pointer with one safety added the conversion to and back is guaranteed, which never was with void* and occasionally cropped up and you can safely do it on any pointer type.
It also means when you look at it in a debugger it shows as an unsigned integer rather than a pointer which is more in keeping with what it really is ... an address to somewhere in CPU memory space.
// I already created these a globals//// HDC HDC_of_FRONT_BUFFER;// HBITMAP Canvas_for_FRONT_BUFFER;// int FRONT_BUFFER_WIDTH;// int FRONT_BUFFER_HEIGHT;// int FRONT_BUFFER_Temp;// The HDC_of_MainWindow was released in elsewhere. So, get it again.
HDC_of_MainWindow = GetDC( Handle_of_MainWindow );
// Create the HBITMAP "canvas", or surface on which we will draw.
Canvas_for_FRONT_BUFFER = CreateCompatibleBitmap( HDC_of_MainWindow, FRONT_BUFFER_WIDTH, FRONT_BUFFER_HEIGHT );
if (Canvas_for_FRONT_BUFFER == NULL)
MessageBox(nullptr,L"failed to create Canvas_for_FRONT_BUFFER",L"Error!",MB_ICONEXCLAMATION | MB_OK);
// Create the HDC "device context", or collection of tools// and brushes that we can use to draw on our canvas.
HDC_of_FRONT_BUFFER = CreateCompatibleDC( HDC_of_MainWindow );
if (HDC_of_FRONT_BUFFER == NULL)
MessageBox(nullptr,L"failed to create the HDC_of_FRONT_BUFFER",L"Error!",MB_ICONEXCLAMATION | MB_OK);
// Permanently associate the surface on which to draw the// ("canvas") (HBITMAP), with the "set of brushes" (HDC).// "select in" the Canvas_for_FRONT_BUFFER into the HDC_of_FRONT_BUFFER.
HBITMAP Temporary_HBITMAP = (HBITMAP)SelectObject( HDC_of_FRONT_BUFFER, Canvas_for_FRONT_BUFFER );
// Delete the "canvas" that the HDC_of_FRONT_BUFFER was going to draw to.
DeleteObject ( Temporary_HBITMAP );
/// Release the dc of the main window itself
ReleaseDC ( Handle_of_MainWindow, HDC_of_MainWindow );
I use the following
StretchBlt(HDC_of_FRONT_BUFFER, 0, 0, W, H, HDC_of_Something, 0, 0, W, H, SRCCOPY);
Then I put it all to the screen with
HDC_of_MainWindow = GetDC( Handle_of_MainWindow ) ;
// Now copy the FRONT_BUFFER to the MainWindow.
HDC_of_MainWindow, // destination buffer, in this case the front buffer.0, // Horizontal start for drawing.0, // Vertical start for drawing.
FRONT_BUFFER_WIDTH, // Width to draw.
FRONT_BUFFER_HEIGHT, // Height to draw.
HDC_of_FRONT_BUFFER, // SOURCE buffer. We are taking from that back canvas.0, // Horizontal start copying from.0, // Vertical start copying from.
SRCCOPY // Just want a straight copy.
ReleaseDC( Handle_of_MainWindow, HDC_of_MainWindow ) ;
I want the listbox to be added to the front buffer (this is not the screen). It is a collection of buffers that I am combining then later placing them to the screen.
Why does the following not work? It works without the ShowWindow part added. It does not show the listbox this way. What should I be doing to put the listbox in the buffer? I do not want to put a final buffer to the screen and then (after that) put the listbox to the screen. I want it all in the buffer and then the buffer alone to be put to the screen.
StretchBlt(HDC_of_FRONT_BUFFER, 0, 0, W, H, HDC_of_Something, 0, 0, W, H, SRCCOPY);
//This does not show up.
How do I add listboxes to a back buffer and use that?
The listbox seems to be there but invisible.
The way that I did it before, the listbox was there but invisible.
I could detect clicking on the area where the listbox was supposed to be was not allowing me to click on the main window.
I click where the listbox is blocking other things, but nothing happens.
It is invisible or just blocking my clicks to the main window. I want to see the listbox and interact with it.
A ListBox is just a Window, so if you call ShowWindow using its handle, then it may cover part of your main window. That in turn will receive a WM_PAINT message and redraw itself, which may well have the effect of hiding the ListBox. I am really having difficulty understanding what you are trying to do here. The most common use of ListBoxes is as part of a DialogBox, or CFormView. If you want it as part of your MainWindow then you need to add it into the client zone, and not overwrite it with the main window.
It is the window (a window) itself which is represented by a listbox that I am interested in being able to place in a buffer and then placing that buffer to the screen.
It could be a textbox (created via a window) or some subclassed window from elsewhere like a subclassed browser window or a subclassed game, etc. I want to be able to put all of this in a buffer before placing the result to the screen. Does that help to explain it?
Here is where this issue was discovered:
I noticed that sometimes on some computers that multiple items show up on the screen one at a time slow enough that I and other people detect a lag in the screen being fully created. Memory overloaded, or cpu overloaded, or too much other programs running for smooth response at the screen level. I do not want that. I prefer that my program places everything in a buffer then places that one cohesive buffer to the screen, and not one piece at a time. I can do this with text. I can do this with bitmaps. I should be able to do this with windows (listboxes, textboxes, subclassed outside windows).
I tried. I studied. I tried placing almost randomly attempts to break through my ignorance of how to do this.
I noticed that sometimes on some computers that multiple items show up on the screen one at a time slow enough that I and other people detect a lag in the screen being fully created. Memory overloaded, or cpu overloaded, or too much other programs running for smooth response at the screen level.
I guess that meant that I was disappointed with my current attempt to add a generic window to a buffer and then to be able to put that buffer to the screen (showing the window).
I have been trying to create or subclass a window (in this example a listbox), and place that window (I guess as a child window?) into or on a buffer, and then place the buffer to the screen. It "did not work." meant that I failed in the attempt.
Same goal of adding a listbox to a back buffer and using that. Generally, the listbox is just an example of some window that I can get a handle of in my attempts.
I am still suggesting you are doing this all wrong but I can fix this problem if you really are manually drawing the list.
To me it sounds like the listbox should be a child within some other window and you are just trying to do this in some crazy manual way. If it was child it would draw itself when needed with zero code needed from you. However if you are manually doing it you could try this
Copy all the code in the WM_PAINT function of your listbox and place it inside a function like so
void PaintMyList (HWND Handle_of_ListBox, HDC Dc)
// Paste your current list box WM_PAINT code here
Now replace the PaintStruct stuff and simply us the HDC passed on the interface and use Handle_of_ListBox
where you need a handle .. okay check it all compiles. So we are clear all you are using from the PaintStruct
is the DC and the DC you are to use is declared on that function interface so you can remove all references
to the PaintStruct.
Now use a variant you posted above with the one call change
HDC_of_MainWindow = BeginPaint(hwnd, &ps);
PaintMyList(Handle_of_ListBox, ps.hdc); // <=== Now the list paints on the DC from the paintstruct
This approach, even if you somehow managed to get it to work, sounds kludgy at best.
If your program is causing this much lag, it sounds as though way too much work is going on in the UI thread. The main/primary thread should do little else besides UI-related stuff. Everything else should be handled by secondary threads.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
"sounds kludgy" is a start. I can accept that as the beginning of a suggested answer.
I can multi-thread. If you are saying that you know of how to solve this by multi-threading and thus placing a window that is (in this example) a listbox (or some other generic window) to a back buffer, I am ready for that instruction. If you simply did not read my original question and then fired off a general cutting response with no valid logic, then I can understand that and it is ok. I have scanned and responded wrongly myself a few times. If you have a valid solution keeping to answering my first post, then I am ready to read it. If you can this with multi-threading, then please tell me how.
I found this lag in someone else's program that I had nothing to do with coding. I do not recall seeing it in any of my current programs that I wrote. Their program is a really nicely written program that does a lot of things well. But, when their program is running and at the same time some other huge programs (plural) with intense cpu use and intense memory use are running, then I saw a lag that was enough for me to see postings of sections of their program to the screen.
If someone is running my programs then however intense the cpu and memory usage is by any other running programs, I do not want the user to see any lag of sections of my main window being put to the screen. I would prefer that my programs get its work done building a screen buffer before placing anything to the screen.
You guys are great. You seem to have misread what I am asking and yet you still gave an answer that I find useful. Thanks. I could use your suggestion of SetThreadPriority for my screen capture of the listbox (in using a dedicated thread for the capture) if I do not find a way to place the listbox into a buffer. I like this site.
I still would like to be able to put a listbox (or other window) into a graphics buffer.
"I write pure C++ with a thin adapter for Windows". That is one of the most impressive comments that I have read on this and most programming sites within the last year. That reads like an advisable goal.
How would you approach a quest like this as my first post explains?
Victor states that you're not doing anything with MFC, so I must have jumped to the wrong conclusion when I saw your code creating a window. I just run my stuff as a console app that ultimately uses nothing but std::cin, although it can also read commands from a file.