|
Quote: because the container allocates the same amount of memory for each entry
that is an interesting fact
modified 10-Aug-22 13:36pm.
|
|
|
|
|
Yes, except for:
1. Why are you using an array size reference in your instantiations? All you should need is:
derivedclass * Derived1 = new derivedclass();
2. Your container is defined to use somebaseclass * types, so your calls to push_back should be:
AllObject->push_back((somebaseclass*)Derived1);
or better still, using proper C++ casts:
AllObject->push_back(reinterpret_cast<somebaseclass*>(Derived1));
|
|
|
|
|
|
You are welcome. I also think @Mircea-Neacsu's advice about unique_ptr is well worth taking.
|
|
|
|
|
pointers from a library, that`s a topic that`s a bit too advanced or complicated for my present day understanding.
|
|
|
|
|
If you can handle raw pointers, then C++ smart pointers should be easy to understand. Google for C++ unique_pointer tutorial and read through a few of the returned hits. It's fairly straight forward, and in general new C++ development should use the smart pointers instead of using raw (e.g. new/delete).
Keep Calm and Carry On
|
|
|
|
|
The problem is I hate complicated syntax. Containers are already complicated syntax for me, combine that with another object (pointer) from a library and it becomes unintelligible mess. I will use a complicated feature when I really need to use it and there is no other way around it. Usually I need to use a feature a couple months before I can move on to something more complicated.
|
|
|
|
|
It's a lot simpler than classes and inheritance.
|
|
|
|
|
Richard you really think so?
|
|
|
|
|
Did you notice the icon?
|
|
|
|
|
|
I guess converting the object(pointer) back to it`s original form when time comes to use it somewhere works the same
derivedclass * DerClpointer1 = (derivedclass *)AllObjects->at(0);
Is there a way to check is the conversion is valid? like if an object is of a certain type. For instance how do I convert all objects to their derived state type in a for loop?
for(int i =0; i< AllObjects->size();i++ )
{
}
modified 13-Aug-22 9:27am.
|
|
|
|
|
Calin Cali wrote: guess converting the object(pointer) back to it`s original form when time comes to use it somewhere works the same Yes it should do, but you need to run some tests to make sure.
|
|
|
|
|
I`m trying to animate things in a basic window. The code I have should get a rectangle (rc) move to the right however that does not happen, it`s all static.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static RECT rcBmp;
static HDC hdcCompat;
static HBITMAP hbmp;
static RECT rc;
static RECT rc2;
static RECT rc3;
static RECT rc4;
HBRUSH hbrWhite, hbrGray;
const COLORREF SomeColor = RGB(255,255,255);
const COLORREF SomeColor2 = RGB(0,0,1);
hbrWhite = CreateSolidBrush(SomeColor);
hbrGray = CreateSolidBrush(SomeColor2);
int y = 0;
HDC hdc = (HDC) wParam;
switch (uMsg)
{
case WM_CREATE:
return 0L;
case WM_ERASEBKGND:
GetClientRect(hwnd, &rc);
SetMapMode(hdc, MM_ANISOTROPIC);
SetWindowExtEx(hdc, 100, 100, NULL);
SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);
FillRect(hdc, &rc, hbrWhite);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
SetRect(&rc,x, 20, 40, 40);
FillRect(hdc, &rc, hbrGray);
SetRect(&rc2,60, 60, 80, 80);
FillRect(hdc, &rc2, hbrGray);
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void GameUpdate()
{
x = x +1;
}
[Edit] it looks like WM_PAINT isn`t triggered every frame, only if I minimize and then maximize the window a change takes place
modified 9-Aug-22 14:35pm.
|
|
|
|
|
I think you need an "event"; like a timer tick; in order to create a "frame loop" (update and paint).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Windows is event-driven, it doesn't have regular animation frame updates.
You can use SetTimer() to get WM_TIMER messages as often as you want, then invalidate your window to get the WM_PAINT message and repaint.
GDI performance is not very good though, so to reduce flicker you'll probably want to draw to an offscreen compatible device context and then BitBlt() that to the screen. Or use Direct2D - but then you'll have a new problem to think about.
|
|
|
|
|
|
I had in mind switching my videogame from DirectX to GDI. After some attempts at getting a win app working the way I need it and failing I will probably give up on the idea. I should probably keep using DirectX. Thanks for your help Richard and everyone else. Sorry for taking your time, this GDI idea is just a dead end.
modified 10-Aug-22 9:06am.
|
|
|
|
|
I would suggest you remove that link from your message (and future ones), as the system assumes it is spam. And some people here will just flag the message which means it will not get published.
|
|
|
|
|
Hi,
I am following an example from a book and it doesn't work fine.
In a win32 c++ project I am trying to make the following codes to work:
At the window creation the mapped file is created
case WM_CREATE:
{
hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE,
0,
1024,
"MyFileMappingObject" );
if ( !hMapFile )
return(-1);
}
break;
There are made modification in mapped file in the following thread function:
DWORD AnotherProcess( LPDWORD lpdwParam )
{
HANDLE hFileMap;
LPTSTR lpMapAddress;
hFileMap = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE,
"MyFileMappingObject" );
lpMapAddress =(LPTSTR)MapViewOfFileEx( hFileMap, FILE_MAP_ALL_ACCESS,
0, 0, 0, lpdwParam );
MessageBox( NULL, lpMapAddress, "Mapped Memmory",
MB_OK | MB_ICONINFORMATION );
strcpy( lpMapAddress, "Received" );
UnmapViewOfFile( lpMapAddress );
return( 0 );
}
There are made modification on mapped file and the thread function is called on the following code:
case IDM_TEST:
{
DWORD dwID;
lpMapAddress = (LPTSTR)MapViewOfFile( hMapFile,
FILE_MAP_ALL_ACCESS,
0, 0, 0 );
strcpy(lpMapAddress, "Data passed from main process.");
FlushViewOfFile( lpMapAddress,
lstrlen( lpMapAddress ) );
hThread = CreateThread( NULL, 0,
(LPTHREAD_START_ROUTINE)AnotherProcess,
lpMapAddress, 0, &dwID);
SetTimer( hWnd, 1, 1000, NULL );
}
break;
If everything is ok all cycle is ended with the timer:
case WM_TIMER:
{
if ( strcmp( lpMapAddress, "Received" ) == 0 )
{
KillTimer( hWnd, 1 );
TerminateThread( hThread, 0 );
MessageBox( hWnd, lpMapAddress, "Done", MB_OK );
UnmapViewOfFile( lpMapAddress );
}
When I put breakpoint in the "AnotherProcess" thread function, after the message box, in the message box no message
is displayed, like lpMapAddress would be empty.
It could be from OpenFileMapping or MapViewOfFileEx to not doing their job? Because in watch table lpMapAddress
has value 0.
After that point, the compiler enters in a kind of assambler code in a inifinite main loop. Maybe here WM_TIMER goes crazy.
Can you help me to figure out what should be done? Where are the things that are nok?
Thank you very much.
|
|
|
|
|
Took me some time to spot the problem (I think):
lpMapAddress =(LPTSTR)MapViewOfFileEx( hFileMap, FILE_MAP_ALL_ACCESS,
0, 0, 0, lpdwParam );
This doesn't make much sense: the last argument of the function is the address where you want it mapped. So you are kind of mapping the memory where it was already mapped. I's suggest to change it to:
lpMapAddress =(LPTSTR)MapViewOfFile( hFileMap, FILE_MAP_ALL_ACCESS,
0, 0, 0);
If you want a shared memory implementation that has been tested, you can find one here. The source file is mlib/src/shmem.cpp
Mircea
|
|
|
|
|
Thank you for the rapid response.
Indeed, now, the code works as I think it should.
I supposed that this was the central idea, to modify the mapped file from two different places, but appears
that something went wrong. I supposed that the LPWORD type of lpdwParam was the problem but I haven't seen a solution.
It appears that it does't like the start address but the all file to be mapped.
Anyway it seems that it's working, and now I can move on in the learning process beacause I want to get the ideea not to
stay to long on each topic.
Thank you very much Mircea for your response and for the links.
Thank you.
|
|
|
|
|
You are very welcome!
Mircea
|
|
|
|
|
Hi,
Please help me understanding the following declaration:
#define EVENBYTE( i ) ((i+7)/8*8)
It represents the definition of function?
If for example I call EVENBYTE( 1 ), the result will be ((1+7)/8*8)?
From where I have extracted de code, the EVENBYTE was called in that way:
int nIconBytes = (EVENBYTE(nWidth)/8)*nHeight;
I don't understand what this kind of declaring is and why to do it in that mode?
Thank you in advance.
|
|
|
|
|
No, it is not a function, it is a macro definition. While, in your case a function defined as:
int evenbyte (int i) {return (i+7)/8*8;} would do the same thing, there is an important difference: a macro definition is expanded at compile time while a function is compiled and later on called at runtime.
When to use one over the other is a question of optimization speed vs memory: a macro definition like your would not incur the overhead of a call but might produce larger code. Meanwhile a function definition would produce smaller code but might take longer to execute.
To solve these type of issues, C++ has introduced inline functions, so in C++ you can write
inline int evenbyte (int i) {return (i+7)/8*8;} and you leave the compiler the choice of expanding it inline (like a macro definition) or make it a function and call it.
One more thing: the macro definition is insensitive to the type of argument. That is both a good thing and a bad thing like in the examples below:
int i1 = 3;
int e1 = EVENBYTE (i1); long i2 = 129;
long e2 = EVENBYTE (e2);
int e3 = EVENBYTE ("abc");
To accomplish the same thing in C++ you would have to use a function template:
template <typename T>
T evenbyte (T i) { return (i+7)/8*8;}
Mircea
|
|
|
|
|