|
1. For starters, DO NOT EVER adjust a user preference because of a defect in YOUR software. That will surely piss off the end users.
2. You are not setting up or processing the clipping region/rectangle in the WM_PAINT correctly, for some reason. For example, if your window is SHRINKING, there should not be any drawing at all. IF your window is EXPANDING, then you should only need to repaint the areas that are newly exposed. Since a dialog does not normally resize, I am thinking that in the code where your dialog is being resized, if you are invalidating the ENTIRE client area, that is where your problem starts. You should only add the parts of the window that are newly exposed to an update region. Then, when the WM_PAINT comes in, your clipping rectangle should represent the area exposed, not the entire client area. Also, you can process the window background erasing. If you erase to the color of the dialog's background, instead of letting the default color (white, usually) come in, there will be less apparent flicker.
|
|
|
|
|
In my class definitions, I declared a public struct with multiple fields. I then declared both a public and private instance of it. The reason why I have the public instance is to be able to transport the manipulated variables or fields to those of the private ones via the Get and Set methods. Does this still follow the principle of encapsulation? Thanks!
|
|
|
|
|
you only need to have on private member variable of you field.
the Get/Set methods will be public, and will access the private data members.
typedef aStruct {
int a;
} aStruct_t;
class AClass
{
private:
aStruct_t myStruct;
public:
void SetValueInMyStruct(int i ){ myStruct.a = i;};
int GetValueInMyStruct(){ return myStruct.a; };
}
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
What if you have many private members/fields in the struct that you would like to access all outside of the class. Then there would have to be a set/get method for each one. Instead can I do the following? I declared a public instance of the struct to handle all kinds of data manipulation within the class and outside before transferring it to the private struct.
class AClass
{
public:
struct aStruct
{
int a;
int b;
int n;
}
aStruct a_struct;
private:
aStruct b_struct;
public:
void Set_StructValues(){b_struct = a_struct};
void Get_StructValues(){a_struct = b_struct);
-------------------------------------------------
void RandomFunction() //function of another class that uses a global
//pointer for the AClass
{
pAClass->a_struct.a = 1;
pAClass->a_struct.b = 1;
pAClass->Set_StructValues();
}
|
|
|
|
|
it depends what exactly you want to expose to "clients'. having a public struct that simply serves as variable holder is somewhat useless.
having 2 members that always need to be manually "synched" is a really bad idea ( if I understand what you describe ).
what happens if, for example, you decide to change the struct "aStruct" ( for whatever reasons ) ? You will need to change each external clients that access directly the public member struct. if you have Get/Set methods that hide the internal struct, the client might ne be needed to change, only the Get/Set method.
if the struct will be be used outside the class, make it external to your class.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
How could I make it external given what I have above? My project includes a checklist that keeps track of all items that needs to be down. Each item, when clicked on, displays a child window that needs some type of user input. Once users have completed the form, a check mark appears on the checklist. The checklist class contains variables that indicate what has been completed. Hence the need for constantly changing the checkmark values. There are several items on the list that needs to updated in several classes. How can I make the struct external and will this work with the design I have in place? Thanks!
|
|
|
|
|
ok, if I understand correctly ...
- Each item in the check list is a structure ( containing the user input ); and is filled in their own child window ( so, a class, with the data )
You could have one big class ( structure ) containing all user inputs for all sub-forms; this class is created by the parent of the sub-forms, and a reference is passed to each sub-form. Each subform can fill (set) the values in that class; and the parent window can get the values, to update the UI; each sub-forms can keep local copies of the data for undo/reset, but those can be discreet values, no need to make a structure out of them.
for example ( very simplified, 2 forms, with one value per form ):
class MyData
{
private:
int m_iForm1Value;
int m_iForm2Value;
public:
void SetForm1Value( int i ) { m_iForm1Value = 1;};
int GetForm1Value( ) { return m_iForm1Value; };
void SetForm2Value( int i ) { m_iForm2Value = 1;};
int GetForm2Value( ) { return m_iForm2Value; };
bool IsForm1Complete(){ return m_iForm1Value != 0; };
bool IsForm2Complete(){ return m_iForm2Value != 0; };
};
class ParentFormDialog : public CDialog
{
private:
MyClass& m_Data;
void SetData( MyClass& data );
}
void ParentFormDialog::OnItem1Clicked()
{
Form1Dialog dlg;
dlg.SetData( &m_Data )
dlg.DoModal();
}
void Form1Dialog::OnOk()
{
int iValue = 1;
m_Data.SetForm1Value( iValue );
}
is this workable ? I think I understand what you want to achieve.
If you really want to have a structure for each sub-form data, make them class and implement a copy constructor, so you can copy them at will.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
I don’t think I have time to go back and make it all subform classes part of a big one. Yes you have the right idea in that each item corresponds to a subform. Thus a form view and a data class per subform. The checklist also has a form view class and a data class much like the subforms. Each data class has a structure to hold data as well as functions to handle the data. Such functions include passing the public data members to the private ones and vice versa (accessors and mutators). The reason why I used structs was because it was easier to transfer multiple data members at one time. Writing data to file was also easier. You just need to pass in the struct object as an argument.
Throughout the program, the data members in the checklist class gets set/reset quite often via the class object created in the main class. Each time the value changes, a call is made to the set function to set the private member to the public one.
Now when you suggested I used copy constructors in each subform, how does that make it easier to pass say 20 member variables to the constructor? Wouldn’t my overloaded constructor be very long with 20 arguments?
I don’t know if I’m confusing you but I guess my question is does my method violate the good coding practice of not having any public data members. That was what I was trying to achieve by having public structs hold variables to pass to the private one. Does that make sense to do it that way? Is there no way of avoiding having to create set/get methods for each private variable in the struct?
|
|
|
|
|
I have an exe that has to be compiled in Unicode. It links with several DLLs also compiled in Unicode. I now have to link it with another DLL that I can't compile in Unicode(it's built from 3rd party, ANSI-C source, plus some 3rd-party binaries).
When the exe link runs (msvc7) I get the messages:
LINK : warning LNK4098: defaultlib 'mfc71ud.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib 'mfcs71ud.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
uafxcwd.lib(appcore.obj) : error LNK2001: unresolved external symbol ___wargv
uafxcwd.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argc
I turned on the linker switch /verbose/lib, which shows all the libs being searched. I went through the libs and removed all that were not required (i.e., that didn't generate new unresolved externs) and it didn't solve the problem. I still have the same two conflict messages and the two unresolved externs.
I think the problem must be conflicting versions of some run-time library, but I can't figure out which. (I know what argv,argc are)
Jim Scott
|
|
|
|
|
Ouch! I am getting a really bad feeling about this.
You might be better to DYNAMICALLY link with the DLL that is not Unicode enabled.
Then you can use WideCharToMultiByte before passing any strings into the non-unicode DLL. Even more power to you if the DLL does not process strings and only other data types. Just use LoadLibrary and GetProcAddress for the few functions you need from the DLL. Write a wrapper class if you have to that will give you a clean interface to the non-unicode DLL.
|
|
|
|
|
Well, passing strings between the Unicode and non-Unicode layers is exactly what I need to do. The non-U functions put their result into an array of strings whose number and lengths are not known before the functions are called. After they return, I plann to convert them from MBCS to Unicode.
Dynamically loading the non-U dll is an idea which I hadn't thought of (haven't had to do it for years, maybe not since the Win3.1 days). That will complicate the passing of strings between the two DLLS, though, since mem will be allocated in one dll and freed in another. Acutally I have to do this anyway; don't know if the dynamic load affects this issue.
Two other possibilities occur to me:
1. Create a console app out of the non-Unicode stuff. This could be spawned by the main app and could write its results to a text file, which could then be read by the unicode app. That's really ugly, but is more or less guaranteed to work.
2. Create an out-of-process COM server out of the non-Unicode component. That may not be possible, since COM is more of less always Unicode.
Jim Scott
|
|
|
|
|
Along the lines of #1, you could make an EXE that is controlled by the Unicode process, and use memory mapped files to communicate between the two programs. It might beat writing a file to disk. Then you can also constrain your memory allocations and frees to the 'same' process using the same memory model. The Non-U process would statically link to the Non-U DLL and write to the memory mapped file. IT sets an event or something, and the Unicode process reads that shared memory and does whatever conversions are required.
|
|
|
|
|
I was experimenting on a worker thread to do a timer which posts a message each second and the thread is created in the CView constructor
(MY APP is SDI)
class CMyView:public CView
{
//consturctor ...
public:
static UINT RunTimer(LPVOID p);
void Run();
public:
volatile BOOL m_bRunTimer;
//other stuff
};
CMyView::CMyView()
{
m_bRunTimer=TRUE;
//Initialize Stuff
AfxBeginThread(RunTimer,this); //Get A Thread To Post A Message Every Second
}
the Run Timer Function is used in This Way
/////////////////////////////////////////////////
UINT CMyView::RunTimer(LPVOID p)
{
((CMyView*)p)->Run ();
return 0;
}
void CMyView::Run ()
{
while (m_bRunTimer)
{
::Sleep (1000);
PostMessage (UWM_TIMER_SECOND);
/*Note Here that UWM_TIMER_MESSAGE IS user Defined Message*/
}
}
every thing works great till this point and the thread posts a message each second and the message handling is doin great the problem arises when the window(program) is closed then a debug assertion failure dialog box is displayed saying the when we are Posting a message we are posting a message to a window that no longer exists.
I tried adding The line m_bRunTimer=FALSE; in ~CMyView() but no change then i wrote some code in the
void CMyView::OnDestroy()
{
m_bRunTimer=FALSE;
::Sleep(4000);//Simply Added to Elapse the Time Slice of Main Thread
CView::OnDestroy();
}
After Doing i finally got safe with removing the thread and returns value i used TRACE() that my thread is safley removed and everything but i think my way of getting rid of the thread is kind of not portable and clean is there any other way that i can do this safley.
|
|
|
|
|
IMO, after signalling the thread to stop you should use WaitForSingleObject.
|
|
|
|
|
I was thinking that the problem could be solved with another safety check.
Make sure the window exists before posting the message!
if( ::IsWindow(m_hWnd) ){
PostMessage (UWM_TIMER_SECOND);
}
Note that you want to invoke the GLOBAL IsWindow and not the class-specific override, that is whyt he :: is in front of the function name.
Now, you avoid your crash, and some other issue you might not have discovered yet.
I always make sure the target window still exists before posting or sending a mesage from a different thread.
Now, if you waited on an event and sets its timeout to 1000 milliseconds, you could signal the event from your main thread, and the timer thread could exit sooner (instead of always being asleep for 1 second).
If you see WAIT_OBJECT_0 you exit the thread, otherwise, if it gets WAIT_TIMEOUT, you just post your message as normal. This way, your main app would not necessarily need to wait 4 seconds, it could exit immediately.
Also, a s the other person suggests, you can wait on the timer thread handle in the main thread to know when the timer thread was done.
|
|
|
|
|
Hello,
I am not sure how this works I am just beginning to learn this.
A and B are objects of the same class named TestClass
in my main i have:
...
if (A != B)
...
.cpp file has the definitions:
this class has one data member:
char* m_Str
//comparison operator !=
bool MGString::operator!=(const char* Src) const
{
bool value;
value = Compare(Src,m_Sensitive);
return value;
}
//compare function
int MGString::Compare(const char* Src, bool m_Sensitive) const
{
int result;
if (! m_Sensitive)
{
result = strcmp(m_Str,Src);
}
else
{
result = strncmp(m_Str,Src,strlen(lino));
}
if (result !=0)
return false;
else
return true;
}
//conversion operator
MGString::operator const char*()
{
return m_Str;
}
this will not compile because strlen can not accept an argument (m_Str) of type TestClass it needs a char*.
I am guessing that the way I have it set up now my conversion operator returns type char* for the data memeber m_Str for object B. However the m_Str for object A is still of type TestClass so in main when the conversion operator is called for B i think it returns a convertred value for m_Str from TestClass to char*. How do I fix this?
thanks,
Lino
|
|
|
|
|
bool operator!=(const TestClass& s1, const TestClass& s2)
{
return Compare(s1.m_Str, s2.m_Str);
}
"Opinions are neither right nor wrong. I cannot change your opinion of me. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
can u elaborate? why is this not a class member?
and i do want to use a conversion operator...are u telling that it would be incorrect of me to use a conversion operator?
can u show me how to use the conversion operator?
thanks,
Lino
|
|
|
|
|
lino_i wrote:
can u elaborate? why is this not a class member?
That was just an example. You could also make it a member, like:
class TestClass
{
operator LPCTSTR() const
{
return m_Str;
}
bool operator!=(TestClass& s1) const
{
return Compare(m_Str, s1.m_Str);
}
};
"Opinions are neither right nor wrong. I cannot change your opinion of me. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
thanks for your patience...
again i am a beginner at all of this but...
looking at this again why do i even need a conversion operator if m_Str is declared a char* private data member when i build my class.
why doesn't this line of code:
if (A != B) call:
bool operator!=(TestClass& sl) const
{
return Compare(m_Str, sl.m_Str);
}
what's the point of the conversion operator?
and in your scenario above what is actually getting converted (the data member of which object?)
thanks,
Lino
|
|
|
|
|
lino_i wrote:
why doesn't this line of code:
if (A != B) call:
bool operator!=(TestClass& sl) const
{
return Compare(m_Str, sl.m_Str);
}
This works fine for me:
class TestClass
{
char *m_Str;
bool Compare(const char *str1, const char *str2) const
{
return (strcmp(str1, str2) == 0);
}
public:
TestClass(){}
~TestClass(){}
operator LPCTSTR() const
{
return m_Str;
}
bool operator!=(TestClass& s1) const
{
return Compare(m_Str, s1.m_Str);
}
}; lino_i wrote:
what's the point of the conversion operator?
If you needed to call a function or method that knew nothing about a TestClass object, but it did understand what a const char* was, it would be used in that context.
"Opinions are neither right nor wrong. I cannot change your opinion of me. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
you have a conversion operator as well...why is it necessary? m_Str is already a pointer?
|
|
|
|
|
lino_i wrote:
why is it necessary?
I didn't say that it was. I was just showing you how to implement one. If there is never a need for users of your class to access m_Str , it can be removed. However, if you did want users of your class to be able to access m_Str , it would be needed. In your case, it would not be considered a "conversion" operator, but simply an "access" operator.
"Opinions are neither right nor wrong. I cannot change your opinion of me. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
There is lots of stuff around on skinning dialogs and dialog controls, but has anyone done anything with skinned CPropertySheet and skinned CPropertyPage ???
|
|
|
|
|
Hello,
I have a function that calls a compare function which does a simple strcmp() comparison. Then in this function I return to the calling function the value of result.
this is my compare function:
bool m_Sensitive = false;
int result;
char lino[] = "value";
if (! m_Sensitive)
{
result = strcmp(lino,Src);
}
else
{
result = strncmp(lino,Src,strlen(lino));
}
return result;
Back in the calling function which returns a bool I need to analyze the return value.
I have tried
if (return !=0)
return false;
else
return true;
this is not working any thoughts?
thanks,
Lino
|
|
|
|
|