|
Thanks again for this link. In reading this, I also found the answer to a quirk I had noticed in using qsort() that is bothering me.
qsort() must be "unstable" according to this document. If for example I pass three items to this qsort, all of which have identical comparison fields (ie: the Type), then the list gets re-ordered anyway! I was trying to figure this out when each return from my sorting function was zero.
Any way to make qsort() "stable" so it won't change things if the comparisons are identical, or another function to use that would give me this result?
Thanks,
|
|
|
|
|
Gunn317 wrote: qsort() must be "unstable" according to this document.
True. It actually has to do with the algorithm itself, not necessarily the qsort() implementation.
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
|
|
|
|
|
instead of just A > B, your test will now be something like:
((A.p1 > B.p1) ||
(A.p1 == B.p1 && A.p2 > B.p2))
in words: if the primary criteria match, test the secondary criteria. if not, you don't have to worry about the secondary.
that should be pretty easy to extend to multiple criteria.
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Thanks for the info. The link and your sample code basically say the same thing.
Now I just have to figure out how to hook this up when I don't know what the user will choose to sort by. We have a listview with a bunch of columns and need the ability for the user to sort up to four of them at once and in priority order.
Currently with just sorting by one field, I have individual functions to pass to qsort to do this:
int SortByType(void *pElem1, void *pElem2);<br />
int SortByName(void *pElem1, void *pElem2);<br />
etc.
They each do a comparison their particular field. But if the user specifies more than one search criteria, I have to figure out how to get that to qsort()...any ideas?
Thanks again,
|
|
|
|
|
this might work: make an array of function pointers, one for each sort function that you'll use, in order. your qsort function would run down that array and call those comparators one at a time until it can tell for sure if A > B. you'll need to be able to test > and =.
it gets tricky to think about, but i get the feeling the code would be pretty small.
--
are you wedded to qsort ? if you can use std::vector, STL's std::stable_sort would make this job a lot easier. you would do something like:
std::stable_sort(data.begin(), data.end(), comparator1);
std::stable_sort(data.begin(), data.end(), comparator2);
std::stable_sort(data.begin(), data.end(), comparator3);
..etc
once per sort criteria, in order of importance.
that won't work
Cleek | Image Toolkits | Thumbnail maker
-- modified at 17:01 Thursday 23rd February, 2006
|
|
|
|
|
Yea, stuck with qsort(). We aren't able to use the STL currently for various reasons....
Thanks for the suggestion, sounds good! I'll work on that idea. So you are saying that in the function that qsort calls, is where I should run through the list of comparator functions?:
qsort( , , , &MySortFcn);<br />
<br />
int MySortFcn(void *p1, void *p2)<br />
{<br />
<br />
return value;<br />
}
|
|
|
|
|
yeah, that's what i was thinking. you call the next comparator any time you get an "A=B" result from the current one. otherwise, you'll know either Apx > Bpx or Apx < Bpx.
i've never tried it, but it feels like it should work.
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Using qsort is old fashioned, you should be using STL - it's faster safer and more flexible. Here's how I'd do it:
----------
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
// Our data.
struct Blah
{
Blah(int Type, const char* pName) :
m_Type(Type), m_pName(pName)
{
}
int m_Type;
const char* m_pName;
};
// Print out a blah.
ostream& operator<<(ostream& s, const Blah& b)
{
s << "Type: " << b.m_Type << ", Name: \"" << b.m_pName << "\"";
return s;
}
// Sort functors.
struct SortByType
{
bool operator()(const Blah& l, const Blah& r) const
{
return l.m_Type < r.m_Type;
}
};
struct SortByName
{
bool operator()(const Blah& l, const Blah& r) const
{
return strcmp(l.m_pName, r.m_pName) < 0;
}
};
struct SortByTypeThenName
{
bool operator()(const Blah& l, const Blah& r) const
{
return SortByType()(l, r) | (!SortByType()(r, l) && SortByName()(l, r));
}
};
// The data.
Blah g_Blahs[] =
{
Blah(1, "George"), Blah(2, "Liam"), Blah(2, "Hank"),
Blah(0, "Abigail"), Blah(1, "Bob"), Blah(0, "Jessica"),
Blah(2, "Con"), Blah(1, "Kyle"), Blah(0, "Faye")
};
int main(int argc, char* argv[])
{
Blah* pBegin = &g_Blahs[0];
Blah* pEnd = &g_Blahs[sizeof(g_Blahs)/sizeof(g_Blahs[0])];
ostream_iterator<Blah> oi(cout, "\n");
// Sort by type.
cout << "Type:\n";
sort(pBegin, pEnd, SortByType());
copy(pBegin, pEnd, oi);
cout << "\n";
// Sort by name.
cout << "Name:\n";
sort(pBegin, pEnd, SortByName());
copy(pBegin, pEnd, oi);
cout << "\n";
// Sort by type and name.
cout << "Type and name:\n";
sort(pBegin, pEnd, SortByTypeThenName());
copy(pBegin, pEnd, oi);
cout << "\n";
return 0;
}
Steve
-- modified at 17:29 Thursday 23rd February, 2006
FIXED error in SortByTypeThenName.
|
|
|
|
|
Thanks for the great code example. Unfortunately, it's not entirely my code, but a team project and as such we aren't able to use STL in this project at this time. But I'll definately hold on to this example for future work.
|
|
|
|
|
Hi,
Anyone know if its possible to make Visual Studio 6.0 compile and link using a different compiler.
I like the VS 6.0 environment but I have to support many DOS apps in my work so I would like to be able to edit with visual studio and when I hit build I would like it to run my MSVC++ 1.5 compiler. I would want to do this on a project by project basis rather than all the time.
TIA
Tony
|
|
|
|
|
Create a utility project, add your .c or .cpp and .h files to it, and define a Custom Build step for each .c and .cpp file that compiles the files using a path to the v1.52 cl.exe.
Finally, in your Post Build step, define the linker command to link your app.
onwards and upwards...
|
|
|
|
|
Hi,
Great thanks
|
|
|
|
|
Hi,
In my app, I want to be notified for device changes. I tried to register for notification using RegisterDeviceNotification() function.
But this function takes window handle as its first param. But my app is console app. How do I have to do this.
I also wanted to receive WM_Device messages.
Can I create a handle to WinMain and use RegisterDeviceNotification() and have a callback window procedure using this handle?? How to do that. How to create a handle to winmain??
If not can I create an invisible window and handle the messages. How do I create an invisible window??
Thanks a lot in advance.
|
|
|
|
|
Manu_81 wrote: I tried to register for notification using RegisterDeviceNotification() function.
But this function takes window handle as its first param. But my app is console app.
Which does not mean that your application cannot create a hidden window for the sole purpose of receiving notifications. This is not an uncommon form of communication between processes.
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
|
|
|
|
|
Hello friends, i'm new to programming community but want to devlop a messenger application which will allow me to chat via text as well as voice messages. if any body out here can help me then please help me out & guide throughout the procedure
Gaurav R. Dixit
|
|
|
|
|
|
Hi all,
I m creating a socket like this and receiving remote socket
CScoket rConnectedSocket ;
CScoket * pSrvSocket;
pSrvSocket = new CSocket();
ASSERT_VALID(pSrvSocket);
pSrvSocket->Create(Agent_Port);
pSrvSocket->Listen();
pSrvSocket->Accept(rConnectedSocket);
..............
.............
...................
pSocketFile = new CSocketFile(&rConnectedSocket);
pArchiveIn = new CArchive(pSocketFile, CArchive::load);
pArchiveOut = new CArchive(pSocketFile, CArchive::store);
now later in code is there any way that I could know that I m still connected to remote socket or not ?
Thanks
ZINC
|
|
|
|
|
Before actually calling DeleteFile or RemoveDirectory functions, I want to 'preview' file/directory removal to see if they succeed. Any ideas how to do this?
thanks!
|
|
|
|
|
Almostr always you will want to try if you can delete it, and if it fails evaluate the error code so you can make suggestions to the user.
You can do basic checks (e.g. is the file read-only) However, you cannot test for all reasons why a delete may fail.
Some of us walk the memory lane, others plummet into a rabbit hole
Tree<t> in C# || Fold With Us! || sighist
|
|
|
|
|
i have a sdi application that draws a bitmap based upon data that is loaded from a file.user choses from the menu what kind of bitmap he wants to see
my problem is that everytime i minimize the window the bitmap disappears.or if i choose to zoomout, it doesnot redraw the actual bitmap rather it draws a smaller version with the larger version of the bitmap still visible.
please help.
|
|
|
|
|
It sounds like you are drawing outside the WM_PAINT handler.
In Windows, you should do all painting in the WM_PAINT handler. Windows calls this handler when necessary (e.g. after minimizing/restoring the window). If your data has changed (selected bitmap, zoom level) call Invalidate
See also
Win32 Paint for beginners[^]
Win32 Paint for Intermediates[^]
Some of us walk the memory lane, others plummet into a rabbit hole
Tree<t> in C# || Fold With Us! || sighist
|
|
|
|
|
i have read the tutorials but i still have difficulty in understanding the fact that should i write the code in the OnDraw() function (in which case i wont know which of the options user may select) or if i write the message handler say OnPaint(), how would i know which options the user has selected and what needs to be repainted. i have tried to using InvalidateRect() but i cant seem to get it to work. everytime the window is minimized the bitmap disappears.
if i display anything using the OnPaint() that i use to handle the WM_PAINT msg then that area stays on the dc mixing onto other drawings.
|
|
|
|
|
OnDraw vs. OnPaint:
You normally use OnPaint. OnDraw is only for implementing activeX controls.
In WM_PAINT, you need to erase the background. There are multiple ways to do it (window class style, WM_ERASEBKGND handler, or simply erasing it in OnPaint)
Your next question is probably "it works but now it flickers" See the CMemDC class here on CodeProject
BTW. there is an old article of mine for displaying a bitmap: http://www.codeproject.com/miscctrl/wndimg.asp[^]
Maybe this helps.
Some of us walk the memory lane, others plummet into a rabbit hole
Tree<t> in C# || Fold With Us! || sighist
|
|
|
|
|
Hi, I was wondering what is the difference of "Multithreaded" and "Multithreaded DLL" options on the Code-Generation tab of the VC++.
I used to compile my application (composed out of several dll files) with "Multithreaded" (default option when migrated my app from VS2003 to VS2005) and it crashed randomly (some times it could even run smoothly for some reasonably long time). However when I switched the option to "Multithreaded DLL" the random crashes didn't occur any more.
Thank you.
|
|
|
|
|
This affects how the C runtime library (which contains all the "standard" functions) is linked.
"Multithreaded DLL" links the DLL version: you need to redistribute vcrt.dll etc. "Multithreaded" links the libraries statically: you have less dependencies, but your binary gets bigger.
For MFC applications, Runtime linkage must match MFC linkage.
Themis wrote: it crashed randomly (some times it could even run smoothly for some reasonably long time). However when I switched the option to "Multithreaded DLL" the random crashes didn't occur any more.
It is hard to say whether this is caused by selecting the wrong runtime (likely), or just a bug in your code that goes unnoticed when linking dynamically and may surface anytime (also likely)
Some of us walk the memory lane, others plummet into a rabbit hole
Tree<t> in C# || Fold With Us! || sighist
|
|
|
|
|