|
I just explained what you have to do; redraw them all, not just the one that has moved. You need to invalidate the entire Window, or ensure that you check each line within the invalidated rectangle. Understanding this basic concept is key to writing Windows applications.
Use the best guess
|
|
|
|
|
Understanding this basic concept is key to writing Windows applications
very true. You had already justified it in your first reply.
|
|
|
|
|
Richarsd just told you! Learn to read before learning to code.
|
|
|
|
|
That is perhaps the most ugliest way to solve the problem and has many horrible disadvantages ... IT IS OLD SCHOOL HORRIBLE DONT DO IT.
Problems you will definitely encounter:
1.) The draw process become slower and slower the more lines you have to draw
2.) As your draw process is contained inside the WM_PAINT message your can't thread it
3.) Your application becomes locked and unresponsive while in the draw process
4.) Every time you resize the window it will redraw all the line database
5.) Every time you move the window order or position it will do an entire redraw
Get an old copy of MS_WORD and open a 1MB image file if you want to see what it looks like.
Old versions of many Cad programs and Corel draw were practically unusable because they used the above technique and we have long since moved on from it.
The correct and more modern way to do this is to create a drawing thread that converts your line database onto a memory DC. That is all the thread does all the time when triggered.
The WM_PAINT message simply puts the last finished memory DC from the thread to screen.
Usually every database alteration is held so you can also undo-redo function it.
The obvious advantages is your program never suffers non responsive or semi locked behavior no matter how complex the drawing gets and the application drawing process does not flash and carry on.
Let me know if you get stuck and I will do a quick stub to show you how it works.
modified 11-Aug-13 11:09am.
|
|
|
|
|
When say the define of function memcpy, I say it.
_CRT_INSECURE_DEPRECATE_MEMORY(memcpy_s) void * __cdecl memcpy(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ size_t _Size);
I say the file sal.h, it says that the macro will tell the compile what the usage about this function. but I do not know the compile will do any operation about this macro. If prompt any error when compiling?
|
|
|
|
|
That macro tells you that you shouldn't use that function because it is prone to errors and exploits.
Use memcpy_s instead.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I can get the linked functions in any file by using IMAGE_IMPORT_DESCRIPTOR, but how in this world I can get their addresses?
Assuming AddAtomA is the target
....
Asm code:
(jmp dword ptr ds:004050b8)in memory address of 004050b8 is 779B9EB8 which is function AddAtomA
so is there any way to show the AddAtomA address while using IMAGE_IMPORT_DESCRIPTOR
or showing the place where it will be called in the program?
|
|
|
|
|
The actual address of a function that is imported from another module is resolved while loading your image. If the other image is a dll then it can be loaded to any address if it has a relocation table. If you are curious about the address of a function whose code is in a builtin system dll then you can ask the function address with (GetModuleHandle() or LoadLibrary()) + GetProcAddress() yourself in your program without reading anything from an exe/dll file as some builtin dlls (kernel32, user32) are loaded to the same virtual address in the virtual memory space of every process in the system (at least on 32 bit windows versions, never tried the 64 bit ones). This is an old trick. This has nothing to do with the IMAGE_IMPORT_DESCRITPTOR of a specific image, this way you retrieve a constant that is guaranteed to be constant from system startup to system shutdown.
|
|
|
|
|
thanks
|
|
|
|
|
You are welcome! Was everything clear?
|
|
|
|
|
BTW, this trick is guaranteed to work only with user32 and kernel32, I never tried it with other dlls. These dlls are usually mapped to 7xxxxxxx addresses as you see in your example.
|
|
|
|
|
pasztorpisti wrote: some builtin dlls (kernel32, user32) are loaded to the same virtual address in the virtual memory space of every process in the system
Don't forget about ASLR![^]
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
You are right, thank you for mentioning. I was playing around with these things long ago...
|
|
|
|
|
The dbt.h is included with #define WINVER 0x510.
This is the only thing - commentary (?) I have been able to find in dbt.h ( Windows7.1 SDK) version.
This header does not defines the RegisterDeviceNotification!
So where is RegisterDeviceNotification actually defined? In which SDK ??
What am I missing ??
typedef struct _DEV_BROADCAST_HANDLE {
DWORD dbch_size;
DWORD dbch_devicetype;
DWORD dbch_reserved;
HANDLE dbch_handle; // file handle used in call to RegisterDeviceNotification
HDEVNOTIFY dbch_hdevnotify; // returned from RegisterDeviceNotification
//
// The following 3 fields are only valid if wParam is DBT_CUSTOMEVENT.
//
GUID dbch_eventguid;
LONG dbch_nameoffset; // offset (bytes) of variable-length string buffer (-1 if none)
BYTE dbch_data[1]; // variable-sized buffer, potentially containing binary and/or text data
} DEV_BROADCAST_HANDLE, *PDEV_BROADCAST_HANDLE;
Any constructive help would be greatly appreciated.
Cheers Vaclav
|
|
|
|
|
MSDN says it's defined in <Winuser.h> .
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
MSDN also says to include <windows.h>
|
|
|
|
|
Simply include <windows.h> as MSDN says.
It works for me.
|
|
|
|
|
The documentation[^] explains which headers to include and versions support this function.
Use the best guess
|
|
|
|
|
Here are my "includes" I put into simple MFC test program and it still fails.
What bugs me is that I found others having same problem and the "solution" was to set WINVER to >0x0500.
AS I stated in OP - dbt.h DOES NOT define that function, only makes refrerence to it.
I am still looking for defintion.
Since it fails same when I comment out the #pragma comment I must be missing something else.
I'll keep looking.
Thanks for your help.
Vaclav
#define WINVER 0x0500
#include <C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\Winuser.h>
#include <stdio.h>
#include <tchar.h>
//#include <strsafe.h>
#include <dbt.h>
#pragma comment (lib,"User32")
Just noticed (in preview) that all #include lines have only #include in it!
|
|
|
|
|
Vaclav_Sal wrote: I put into simple MFC test program That is probably the problem when using a stdafx.h file. That files includes various MFC includes which will include the standard Windows header files. So WinUser.h has been already included.
Solution:
Put the WINVER definition on top of your stdafx.h .
Tip:
Format code blocks using the code option above the editor window. Then the <> brackets are treated as they are and not as HTML tag delimiters.
|
|
|
|
|
Solution:
Put the WINVER definition on top of your stdafx.h.
Thanks
|
|
|
|
|
Thanks for posting the solution.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Vaclav_Sal wrote: Just noticed (in preview) that all #include lines have only #include in it! Yes, because as has been suggested before, you should put your code blocks between <pre> tags (use the code button) like:
#define WINVER 0x0500
#include <C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\Winuser.h>
#include <stdio.h>
Vaclav_Sal wrote: AS I stated in OP - dbt.h DOES NOT define that function, only makes refrerence to it. The link to the documentation that I provided earlier, clearly states that this function is defined in winuser.h and suggests including windows.h to get it. That will also ensure that you get the correct WINVER value for the platform you are building on.
Also, judging by the fact that you have to provide the full path for C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\Winuser.h , your installation of Visual Studio has not been set up correctly, as this directoy should be one of the default include locations for all projects.
Use the best guess
|
|
|
|
|
I have a question regarding the following program. This program uses random variables and asks the user to enter the correct sum for 5 times. Until, we enter an integer the program runs well but as soon as we enter any double value or a character, the program gives incorrect message for the whole loop and comes out of the loop automatically. Why does this happen? Can anyone help me?
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
int num1=0;
int num2=0;
int correctanswer=0;
int useranswer=0;
srand(static_cast<int>(time(0)));
for (int x=1; x<6; x++)
{
num1=1+rand()%(100-1+1);
num2=1+rand()%(10-1+1);
correctanswer= num1+num2;
cout<<"What is the sum of "<<num1<<" and "<<num2<<"?"; cin>>useranswer;
if (useranswer==correctanswer)
cout<<"Excellent! Correct Answer";
else
cout<<"Sorry!the correct answer is: "<<correctanswer; cout<<endl<<endl;
}
system("pause");
return 0;
}
|
|
|
|
|
The problem is that in case of a wrong answer you leave garbage in your iostream plus the error flags of the iostream may remain set.
A slitly better but still buggy version:
#include<iostream>
#include<ctime>
#include <limits>
using namespace std;
int funccccc()
{
int num1=0;
int num2=0;
int correctanswer=0;
int useranswer=0;
srand(static_cast<int>(time(0)));
for (int x=1; x<6; x++)
{
num1=1+rand()%(100-1+1);
num2=1+rand()%(10-1+1);
correctanswer= num1+num2;
for (;;)
{
cout<<"What is the sum of "<<num1<<" and "<<num2<<"?"; cin>>useranswer;
if (!cin.fail())
break;
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
cout << "Invalid value!" << endl;
}
if (useranswer==correctanswer)
cout<<"Excellent! Correct Answer" <<endl;
else
cout<<"Sorry!the correct answer is: "<<correctanswer; cout<<endl<<endl;
}
system("pause");
return 0;
}
The bug in this version is the following:
Lets say you answer 5.6 for the first question. In this case your first cin>>useranswer statement will read out "5" into the useranswer by ignoring everything from the input stream from the '.' character. It evaluates the first question with your answer '5' and then it asks the next question. Since we still have characters in the input stream the cin>>useranswer statement of the next question tries to read it as an integer. Unfortunately it fails and our error handler clears the error flags and discards everything from the input stream till the next newline character. From the next question everything is OK. If you simply enter a garbage string that doesn't start with a digit then it works perfectly. The bug of this solution occurs if you enter a garbage string whose first character is a digit like "5sfldfhwei".
You could correct this by always reading in everything till the next newline, stripping the spaces from the left and right side of the string and trying to interpret it as it is without ignoring any characters in the string. I'm not a big iostream fan/user and I don't know how to interpret a string as an integer with iostream without ignoring any characters from the right side of the string.
|
|
|
|