|
Hi,
I want to create an MFC MDI Application, which is used to draw engineering 2D drawing. A similar one to Auto CAD 2D software.
Can anyone of you suggest us the best open source library which we can use to implement 2D mfc drawings.
I know some of libraries like OpenGL, DirectX but i am not sure a) whether we can use these libraries to create 2D drawings. b) whether we need to purchase these libraries as we are developing a commercial application. c) there may be better libraries available for 2D drawing and it may be for free.
Thanks,
Regards
Maha
|
|
|
|
|
OpenS-CAD, a simple 2D CAD application [here].
2D Drawing - Doc/View architecture [here].
CadLib for creating DXF(Drawing Interchange Format) files [here].
|
|
|
|
|
We have in many places in our code things like :
(pseudo-code)
if ( string.compare(A) == 0 )
{
}
else if ( string.compare(B) == 0 )
{
}
else if (string.compare(C) == 0 )
{
}
else if (....)
{
}
else
{
}
I know that we cannot use switch cases for strings, but is there a better way to do cascading If comparisons on strings ?
(This is not urgent ).
Thanks.
Max.
Watched code never compiles.
|
|
|
|
|
Two optimization tricks:
1. You store the possible values (A, B, and C, ...) in a sorted array and you search your string in that array with binary halving. Alternatively you can store A,B,C in one of these: map/hashmap/search tree.
2. If you opt for using == and/or != with if/else then you can speed up these operations for strings by storing the hash value for each string. When you compare two strings you first compare the hash values. If the hash is different then you have your result immediately (false for == and true for !=). If the hash for the strings is different then you have to perform the actual comparison on the strings. I usually write a special string class that contains the hash as well. It has the drawback that the hash must be updated before comparisons if the string has been modified since the last hash calculations. Sometimes purely written old legacy code can be tweaked very well with this trick. Use djb2 to hash your strings, for unicode use utf8: http://www.cse.yorku.ca/~oz/hash.html[^]
EDIT: Just noticed my answer isn't exactly the what you are searching for, but I think there is no fine solution to your problem. This problem is similar to the typical factory patterns that are used to instantiate a specific type by name:
template <typename T>
class StringSwitch
{
public:
void SetInstance(T* instance)
{
m_Instance = instance;
}
void RegisterHandler(const std::string& s, void (T::*handler)())
{
m_SwitchTable[s] = handler;
}
bool PerformOperation(const std::string& s)
{
auto it = m_SwitchTable.find(s);
if (it == m_SwitchTable.end())
return false;
(m_Instance->*(it->second))();
return true;
}
private:
std::map<std::string,void(T::*)()> m_SwitchTable;
T* m_Instance;
};
class BlahBlah
{
public:
BlahBlah()
{
m_SwitchTable1.SetInstance(this);
m_SwitchTable1.RegisterHandler("A", &BlahBlah::StringA);
m_SwitchTable1.RegisterHandler("B", &BlahBlah::StringB);
m_SwitchTable1.RegisterHandler("C", &BlahBlah::StringC);
}
void StringA()
{
printf("%s\n", __FUNCTION__);
}
void StringB()
{
printf("%s\n", __FUNCTION__);
}
void StringC()
{
printf("%s\n", __FUNCTION__);
}
void Run()
{
m_SwitchTable1.PerformOperation("B");
}
private:
StringSwitch<BlahBlah> m_SwitchTable1;
};
int main()
{
BlahBlah b;
b.Run();
return 0;
}
Your refactorized if/else is inside BlahBlah::Run()
modified 23-Aug-12 11:09am.
|
|
|
|
|
You can choose to store strings in buffers of length 4*n. That way you can compare two DWORD vectors. It will be case sensitive, but faster than strcmp. You can also use switch on the first DWORD, but !!!ONLY!!! if no two strings share the same 4 bytes at the begining.
Also, Pascal strings.
|
|
|
|
|
Triky solution ! Got my 5 !
|
|
|
|
|
A minor optimization would be to order your comparisons from most-likely-to-match down to least-likely-to-match. That way, your if test block is exited as soon as possible.
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Maximilien wrote: t is there a better way to do cascading If comparisons on strings
Where "better" means what?
If you just don't like looking at the code then you could do code generation.
If there is a actual profiled performance problem traced to this then you can used collected data to order the comparisons with most used first and least used last. Depending on the number of strings, and the data in the strings other optimizations are possible.
One solution again dependent on data and usage is to parse the input, when first received, into a value such as an enumeration and only use that in the rest of the code.
If there is a lot of churn with these then generation can still help but dynamic collections might solve that, with care. However such solutions might not be as performant and add some level of complexity.
|
|
|
|
|
I give you a little solution (MFC way):
CStringList List;
List.AddTail(A);
List.AddTail(B);
List.AddTail(C);
List.AddTail(D);
....
if(NULL != List.Find(string))
{
}
|
|
|
|
|
What do you mean with 'better'?
If you mean 'more good looking', then I suppose your code becomes 'ugly' only if some of your // do someting for ... is long (I mean, switch , in my opinion, isn't much better than the if -chain).
A completely different approach would be transforming the // do something for .. pieces of code into functions (or function objects) and then use a std::map to map the strings to the function pointers (or function objects).
Veni, vidi, vici.
|
|
|
|
|
1. for each string in your list, register a domain name: A.com, B.com, C.com, etc..
2. on each site, install a web service that will return the code to be used in the "// do something for A" and "// do something for B", sections.
3. your code then calls out to the web service hosted at: "http://" + string + ".com"
4. it will receive the code it needs to execute
code = getCodeFrom("http://" + string + ".com");
exec(code);
it's up to you which language you use for the code, but you will obviously need an interpreter of some kind.
|
|
|
|
|
I'll try it.
Veni, vidi, vici.
|
|
|
|
|
+5. Absolute professional approach, however you forgot to mention the use of some useful frameworks/middlewares.
|
|
|
|
|
That would freak out my code-reviewer !!!
Watched code never compiles.
|
|
|
|
|
Can you reduce the scope of your problem space?
By that I mean: The broad example presumes that the input can be essentially anything.
Change that such that the input can begin with only certain strings or must contain certain keywords. Then you can divide the code up into different sections depending on how the input string can be grouped.
Thanks for your time
|
|
|
|
|
Hi all,
How can i run the bat file using SghellExecute.I am trying with the below code.
ShellExecute(NULL,_T("open"),_T("cmd.exe"),_T("/C Test.bat"),0,SW_SHOW);
Note : Test.bat file path is "C:\Test.bat"
I am unable to run the bat file.Am i doing anything wrong..??
But when i manually click on Test.bat with the mouse,The bat file executes fine.
Thanks in Advance
Manju
|
|
|
|
|
Try the following.
ShellExecute(NULL,_T("open"),_T("cmd.exe"),_T("/C C:\\Test.bat"),0,SW_SHOW);
I suspect that when cmd.exe is run, it is unable to find the file Test.bat.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
|
|
|
|
|
Instead of
ShellExecute(NULL,_T("open"),_T("cmd.exe"),_T("/C Test.bat"),0,SW_SHOW);
use either this:
ShellExecute(NULL, _T("open"), _T("cmd.exe"), _T("/C C:\\Test.bat"), NULL, SW_SHOW);
or this:
ShellExecute(NULL, _T("open"), _T("cmd.exe"), _T("/C Test.bat"), _T("C:\\"), SW_SHOW);
Note that the two solutions are not equivalent. In the second solution the current directory of your batch file will be C:\ while in the first case cmd.exe will inherit the current directory of the program from which you call ShellExecute() .
|
|
|
|
|
Hi all,
I am trying to write one string to a file.But i am getting only one character
saved in my Text.txt file.Output text file contains only "a" in it.
How can i get whole string saved in my text file.
Here is the code i am trying:
FILE *fptr;
CString Text;
Text = "asdasdasdasd";
fptr = fopen("D:\\Test.txt","w+");
if(fptr== NULL)
exit(1);
fprintf(fptr ,"%s",Text);
fclose(fptr);
If i write it as ""asdasdasdasd"" instead of passing the CString,it writes in the text file
fprintf(fptr ,"%s",""asdasdasdasd"");
Can anyone help me,where i am going wrong.
Thanks
Manju
|
|
|
|
|
I suspect your CString may be defaulting to Unicode (check your project settings), so it appears as though you have only written a single character. Try using CStringA and see what happens.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
I suspect you are right.
Veni, vidi, vici.
|
|
|
|
|
No, I think pasztorpisti is right, the string needs to be cast to LPCTSTR to get the content.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Now I'm quite confident you are right.
Veni, vidi, vici.
|
|
|
|
|
I hope your confidence is not misplaced.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
The Text parameter you pass to fprintf() is a CString object, and and the %s format specifier expects a (const char*) or (char*) there. Instead of this you are pushing the whole CString object to the stack and the first 4 bytes of that CString instance are used as a (const char*). You have to convert the CString to either (const char*) or (char*) before using it with fprintf() . A more strict compiler like g++ would warn you about passing a non-pod object to a vararg function.
|
|
|
|