Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Vanadium
Jan 8, 2005

Mustach posted:

A good quick reference for the Standard Library is Apache's documentation.

I would suggest just using the documentation of your actual documentation of the standard library.

Adbot
ADBOT LOVES YOU

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Vanadium posted:

I would suggest just using the documentation of your actual implementation of the standard library.
It has benefits, though. It loads fast (unlike MSDN), it covers more and is better-formatted than SGI's, and is easier to browse than GNU's. If you're only interested in standard stuff it doesn't matter which implementation's docs you're looking at, as long as they indicate what things are extensions.

POKEMAN SAM
Jul 8, 2004

Mustach posted:

(Although a lot of the time they'll say "Visual C++" and mean C++/CLI.)

Where do they do this?

Lexical Unit
Sep 16, 2003

Mustach posted:

It has benefits, though. It loads fast (unlike MSDN), it covers more and is better-formatted than SGI's, and is easier to browse than GNU's.
I remember you posted about this (or maybe it was someone else) just a while back, and I quickly added it to a list of bookmarks regarding this sort of reference information:
  • cppreference - Good quick reference, but a little lacking in details.
  • SGI Reference - More details about STL concepts and such.
  • cplusplus - Seems to have more information about streams/streambus/etc than others.
  • boost - If you can use boost, do it.
  • libstdc++ Source Level Documentation - I guess you'd be use MSDN instead of this.
  • C++ FAQ - Sometimes offers insights idioms and other more obscure things.
  • C Guide - I sometimes have to interact with C or Cish-C++ code.
  • POSIX Reference - Good stuff to know about, except if you're just only dealing with Windows I guess.
  • The Standards - If all else fails.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Ugg boots posted:

Where do they do this?
I just ran into an example in VS2008 yesterday: I was messing around with the unit test wizard and saw that it had a "Visual C++ Test Project" option. I tried it on an unmanaged project and it failed, mentioning some dlls couldn't be loaded because they weren't .NET (or something along those lines, I'm going from memory). The more I think about it, most of the places I've seen it have been in wizards.

FearIt
Mar 11, 2007
I'm trying to find all the handles of windows with a certain class type. FindWindow() only seems to return the first, how would I get the rest?

csammis
Aug 26, 2003

Mental Institution

FearIt posted:

I'm trying to find all the handles of windows with a certain class type. FindWindow() only seems to return the first, how would I get the rest?

Use EnumWindows, like Pooball said, and GetClassName in the EnumWindowsProc to determine if the window is the class you want.

more falafel please
Feb 26, 2005

forums poster

Let's say I have a very large (~1.5 million lines, ~10k files) VC++ solution, with about 10 projects, all with interdependencies. Let's also say that with a relatively small amount of effort, I could turn that into about 50 projects, probably much more intertwined. Currently the ~10 projects each generate a static lib which is linked into the executable.

What would be involved in making each of these new ~50 projects (with the exception of one, and some external libs) generate DLLs in debug or optimized debug builds, and have them linked in at runtime? What kind of startup performance impact would be involved with turning one giant 45 meg executable into a tiny executable and 50 DLLs that get loaded at startup?

The goal of this would be to reduce incremental link times, which are currently about 5 minutes. Hopefully, if only one of these DLLs got changed, the link time would be nearly nonexistent... right?

FearIt
Mar 11, 2007

csammis posted:

Use EnumWindows, like Pooball said, and GetClassName in the EnumWindowsProc to determine if the window is the class you want.

I've been googling enumwindows for a couple hours now and I'm not sure exactly how its to be used, anyone have a link of an example?

ehnus
Apr 16, 2003

Now you're thinking with portals!
Have you come across the MSDN page for EnumWindows?

http://msdn.microsoft.com/en-us/library/ms633497(VS.85).aspx

FearIt
Mar 11, 2007

ehnus posted:

Have you come across the MSDN page for EnumWindows?

http://msdn.microsoft.com/en-us/library/ms633497(VS.85).aspx

Yeah, I've seen that page, I guess something's just not clicking. I tried writing it into my code but I'm not even sure how to parse the handles that have the correct class type or even how to get them out of the callback function once I do so..

Pooball
Sep 21, 2005
Warm and squishy.
This might be more confusing than helping, but there is a Spy++ clone called WinSpy with source code available.

Look for WinSpyTree.c. It uses the handy function EnumChildWindows to get all windows, even children of top-level windows:
EnumChildWindows(GetDesktopWindow(), AllWindowProc, (LPARAM)<some parameter>);

http://www.catch22.net/software/winspy

TheSleeper
Feb 20, 2003

FearIt posted:

Yeah, I've seen that page, I guess something's just not clicking. I tried writing it into my code but I'm not even sure how to parse the handles that have the correct class type or even how to get them out of the callback function once I do so..

It's been a long time since I've done any windows api stuff(not since college), but I think I used to do something like:
code:
success = EnumWindows( myEnumFunc, (LPARAM) &whateverclass);
Then in the enum function casting that lparam back into a pointer to whatever class you're using to collect handles or whatever.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

more falafel please posted:

What kind of startup performance impact would be involved with turning one giant 45 meg executable into a tiny executable and 50 DLLs that get loaded at startup?
The cost of loading a dll is independent of the dll's size. With that many dlls, your startup time will may be noticeably worse than simply paging in the big executable (especially if any of the dlls have to be searched for). You might want to look into Delay-Loaded DLLs if you decide to go this build route.

quote:

Hopefully, if only one of these DLLs got changed, the link time would be nearly nonexistent... right?
Since you'd probably be doing implicit linking of your dlls, .lib files will be created. Each consumer of a dll will have to link to that dll's lib. If you make a change that requires rebuilding the lib, all dependend dlls and executables will have to re-link. The alternative is to use explicit linking, but with that many dlls, it would probably be a bigger hassle than your current 5-minute link times.

FearIt
Mar 11, 2007
I've been having some trouble understanding EnumWindows() so Im about to just try to run a loop with GetWindow() and the GW_HWNDNEXT flag.

As I'm looping through these HWNDS I plan on just comparing the classes until I find matches, but how do I find the class name if I know only the HWND?

TheSleeper
Feb 20, 2003
Uh, GetClassName?

EnumWindows() isn't that hard and is really the way you should do this.

As it says on msdn's EnumWindows page:

quote:

This function is more reliable than calling the GetWindow function in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.

To use EnumWindows all you have to do is call it with your loopback function as the first parameter and whatever you want else cast to a LPARAM as the second. In your loopback you cast your LPARAM back to whatever it was before, do what you want to do and as long as everything goes ok, return true. Your loopback gets called until there are no non-child windows left(as long as you always returned true, if you return false it drops back out to the calling function) and when that's the case, you're dropped back in your calling function with a return value of true.

It's been a really long time since I've had to do this, but I'm pretty sure this is about how it has to go:
code:
BOOL CALLBACK myUselessCallBack(HWND hwnd, LPARAM lParam);

int someFunction(long stuffGoesHere)
{
     SomeCollection whatever;
...
     bool yayItWorked = EnumWindows(myUselessCallback, (LPARAM) (&whatever));
...
}

BOOL CALLBACK myUselessCallBack(HWND hwnd, LPARAM lParam)
{
     char name[30] = "";
     SomeCollection *whatever = (SomeCollection *) lParam;

     GetClassName(hwnd, name, 29);

     if( !strcmp(name,"ClassName") )
          whatever->add(hwnd);

     return true;
}

TheSleeper fucked around with this message at 13:43 on Sep 12, 2008

Zx
Mar 13, 2006
*<|:I

FearIt posted:

I've been having some trouble understanding EnumWindows() so Im about to just try to run a loop with GetWindow() and the GW_HWNDNEXT flag.

As I'm looping through these HWNDS I plan on just comparing the classes until I find matches, but how do I find the class name if I know only the HWND?

I was bored, so here's an example:

code:
#include <windows.h>

BOOL CALLBACK EnumWindowsProc(HWND windowHandle, LPARAM param)
{ 
	char windowClassName[256] = {0};

	GetClassName(windowHandle, windowClassName, sizeof(windowClassName));

	if (strcmp(windowClassName, (char*) param) == 0)
	{
		printf("Found class '%s' @ 0x%.8X\r\n", windowClassName, windowHandle);
	}

	return (TRUE);
}

int main()
{
	char windowClassToFind[] = "ClassNameToFind";

	EnumWindows(EnumWindowsProc, (LPARAM)windowClassToFind);

	return (0);
}

edit: beaten :argh:

FearIt
Mar 11, 2007
Wow TY both, goons to the rescue!

fake edit: how would I incorportate these both into an existing class? or could it be as easily as copy and pasting it in or putting my className::callback ... ?

FearIt fucked around with this message at 22:22 on Sep 12, 2008

TheSleeper
Feb 20, 2003
Uh, you do it the same way you integrate any other function into a class. Are you new to C++? If so it might help to do some more reading and sure yourself up on the basics. Not being solid on that stuff now can REALLY come back to bite you in the rear end later.

FearIt
Mar 11, 2007

TheSleeper posted:

Uh, you do it the same way you integrate any other function into a class. Are you new to C++? If so it might help to do some more reading and sure yourself up on the basics. Not being solid on that stuff now can REALLY come back to bite you in the rear end later.

Nah, I'm pretty versed in C++, I've just never dealt with CALLBACK functions before.

FearIt
Mar 11, 2007
error C3867: 'interfaceDesktop::EnumWindowsProc': function call missing argument list; use '&interfaceDesktop::EnumWindowsProc' to create a pointer to member

I got the following error on the line

EnumWindows(EnumWindowsProc, (LPARAM)windowClassToFind);

I'm not sure what I should do :(

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
You can't use a class member function as a callback. How would it know what "this" is? :colbert:

Use a static or free function.

FearIt
Mar 11, 2007
Ok I've taken the function out of the class but now I get an

error C2664: 'GetClassNameW' : cannot convert parameter 2 from 'char [256]' to 'LPWSTR'

on the line

GetClassName(windowHandle, windowClassName, sizeof(windowClassName));

I've tried casting windowClassName as an (LPWSTR) but then the code compiles but does nothing.

Edit: I figured it out, VS was preset to unicode, I changed to to multibyte and it worked fine, thanks for your help!

FearIt fucked around with this message at 00:22 on Sep 13, 2008

ShinAli
May 2, 2003

The Kid better watch his step.

haywire posted:

Where should I start? Are there any good goon recommended free tutorial sites I can busy myself with before I sink money into a good book?

Right now I'm going through the Accelerated C++ book as all others really piss me off and don't move fast enough for me. It does get a little "THIS HOW YOU PRINT "HELLO WORLD" GEE WIZ" in the beginning but it picks up the pace a little faster and teaches you actually useful things first, then goes deeper into them in the later chapters. I'm going to skim through Thinking in C++ vol 1 since I think Bruce knows what he's talking about, and try to look into vol 2.

I'm also taking a course called "Advanced Programming" that goes through everything in the beginning programming courses up to Data Structures, but this time in C. I like my prof. since he's making me get off my lazy rear end and learn some *nix.

floWenoL
Oct 23, 2002

FearIt posted:

I've tried casting windowClassName as an (LPWSTR) but then the code compiles but does nothing.

This is the worst way to solve compile errors in C/C++.

Your solution isn't that great either. Why not pass in L"MyString" or _T("MyString")? (I forgot the right one to use.)

floWenoL fucked around with this message at 04:35 on Sep 13, 2008

ehnus
Apr 16, 2003

Now you're thinking with portals!

floWenoL posted:

This is the worst way to solve compile errors in C/C++.

Your solution isn't that great either. Why not pass in L"MyString" or _T("MyString")? (I forgot the right one to use.)

The documentation for GetClassName() says it takes an LPTSTR, which you construct with _T("MyString")

(don't forget to include tchar.h!)

newsomnuke
Feb 25, 2007

Not strictly a C++ question, but pretty close. I have a memory issue which I don't understand. My executable loads a DLL, which contains various managers for my game.

When I have a class which is exported by the DLL, and I create an instance of it in the executable, hand it back to the DLL and then delete that instance in the DLL, I get a memory fault. Likewise, if I have a class defined in my exe which I pass over to the DLL (eg an abstract factory), and then delete that class in the DLL, I get a fault. On the other hand, if a class is defined and instantiated by the exe, and then given to the DLL which deletes it, everything is OK.

I'm using the same multi-threaded DLL CRT for everything, so I don't quite know what's up.

edit: I realise handling memory like this is bad practice, and I intend to refactor, I'm just curious because I haven't been able to find a reason why this doesn't work.

newsomnuke fucked around with this message at 13:37 on Sep 13, 2008

That Turkey Story
Mar 30, 2003

ultra-inquisitor posted:

Not strictly a C++ question, but pretty close. I have a memory issue which I don't understand. My executable loads a DLL, which contains various managers for my game.

When I have a class which is exported by the DLL, and I create an instance of it in the executable, hand it back to the DLL and then delete that instance in the DLL, I get a memory fault. Likewise, if I have a class defined in my exe which I pass over to the DLL (eg an abstract factory), and then delete that class in the DLL, I get a fault. On the other hand, if a class is defined and instantiated by the exe, and then given to the DLL which deletes it, everything is OK.

I'm using the same multi-threaded DLL CRT for everything, so I don't quite know what's up.

edit: I realise handling memory like this is bad practice, and I intend to refactor, I'm just curious because I haven't been able to find a reason why this doesn't work.

Never delete memory allocated in an exe from a DLL or the other way around. Call the corresponding delete for each object -- people often accomplish proper deletion by adding a virtual "release" member function that simply calls delete this. Call that function instead of calling delete.

That Turkey Story fucked around with this message at 23:03 on Sep 13, 2008

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
Anyone have a decent resource for serial communication with C++? Googling yields lots of links with dubious quality.

newsomnuke
Feb 25, 2007

That Turkey Story posted:

Never delete memory allocated in an exe from a DLL or the other way around. Call the corresponding delete for each object -- people often accomplish proper deletion by adding a "release" member function that simply calls delete this. Call that function instead of calling delete.
I must be getting confused about which side of the boundary the allocations are being made. In my DLL I have a class Application, which I create an instance of in the exe. Then, I create a factory class (which is defined in the exe), and give it to the Application. Then I use this factory to create a concrete instance:

code:
Core::Application *app = new Core::Application;
app->addArchiveFactory (new DirectoryArchiveFactory("Directory"));
app->addArchive("Directory", "./Resources/");

...

delete app;
Application::addArchive pseudocode
code:
Application::addArchive(...)
{
    Archive *arc = new Archive;
    mArchives.push_back (arc);
}
Application::~Application pseudocode
code:
Application::~Application()
{
    foreach FactoryArchive i
        delete i; // Can delete FactoryArchives fine

    foreach Archive i
        delete i; // But can't delete Archives, memory fault
}
It seems to me that the Archive is being created & destroyed by the Application object, so surely that should be OK? Application counts as 'belonging' to the exe because that's what allocated it, right? And any direct allocation done by the Application would belong to whatever created the Application?

I was also under the impression that if you used the DLL CRT, then exe and DLL would use the same heap manager, so this wouldn't happen in the first place, but I guess I'm missing something.

Chuu
Sep 11, 2004

Grimey Drawer
n/m

Chuu fucked around with this message at 23:44 on Sep 13, 2008

Vanadium
Jan 8, 2005

That Turkey Story posted:

Never delete memory allocated in an exe from a DLL or the other way around. Call the corresponding delete for each object -- people often accomplish proper deletion by adding a virtual "release" member function that simply calls delete this. Call that function instead of calling delete.

Can you elaborate on what the deal is with that? I have no idea how Windows works, but that sounds somewhat silly.

Thug Bonnet
Sep 22, 2004

anime tits ftw

On Linux, using Ncurses' getch() blocks by default, waiting for input, on Windows using Cygwin it doesn't for some reason. Anyone know why?

I tried specifying nocbreak() for "cooked mode" and it didn't seem to help.

code:
#include <ncurses.h>

int main(){
	initscr();
	printw("Hello world!");
	refresh();
	nocbreak();
	getch();
	endwin();

	return 0;
}

mistermojo
Jul 3, 2004

I need some help on an assignment (this is like the very first thing I've done in C so I'm sure the code is really gay and stupid)

The point is to scan in an input.txt file, which is just a bunch of numbers separated by lines, with the first number being how many numbers there are. Then we're supposed to bubble sort it and print out the numbers.

The problem is that instead of numbers, it prints random characters?? I have no idea

code:
#include <stdio.h>

int main()
{
  int newarray[2000];
  int i,j,temp;
  FILE * fp;
  fp = fopen("input.txt", "r");
  i = 0; 
  while(!feof(fp)){
  
  fscanf(fp,"%d",&newarray[i]);
  i++;
  }
  fclose(fp);
  int lines = newarray[0]; 

  for (i = lines; i >= 1; i--)
    {
      for (j = 1; j <= i; j++)
	{
	  if (newarray[j-1] > newarray[j])
	    {
	      temp = newarray[j-1];
	      newarray[j-1] = newarray[j];
	      newarray[j] = temp;
	    }
	}
    }
  for (i = 1; i < lines; i++)
    {
      printf("%c\n", newarray[i]);
    }
  return 0; 
}
A sample input.txt would be
code:
5
100
315
200
50
70
and my output was
code:
2
F
d
È
zuh???

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
That's because you're telling it to print a character. "%c" is "print a character". You want "%d"

mistermojo
Jul 3, 2004

Avenging Dentist posted:

That's because you're telling it to print a character. "%c" is "print a character". You want "%d"

Oh, duh, I changed it to d for the scan but not for the second line. Thanks.

Pooball
Sep 21, 2005
Warm and squishy.

Thug Bonnet posted:

On Linux, using Ncurses' getch() blocks by default, waiting for input, on Windows using Cygwin it doesn't for some reason. Anyone know why?

I tried specifying nocbreak() for "cooked mode" and it didn't seem to help.
[/code]



getch man page:
In no-delay mode, if no input is waiting, the
value ERR is returned. In delay mode, the program waits until the
system passes text through to the program.

nodelay man page:
The nodelay option causes getch to be a non-blocking call. If no
input is ready, getch returns ERR. If disabled (bf is FALSE),
getch waits until a key is pressed.

It doesn't say what the default option is. I guess it might be inherited, which would explain the difference in behavior.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Stupid question time.

I'm sure that this is a really trivial problem, but unfortunately I'm retarded when it comes to strings; I can't internalise how they work at all, or even really understand them.

I have a string StringX in the form of an LPSTR (that is, char*). I don't have the option of trying to use another string data type because LPSTR is the form in which Windows returns the string from the function used to obtain it. I want to test whether that string is the empty string, "".

StringX is a global variable of type LPSTR. I use the function GetWindowText(TextBoxHwnd,StringX,25) to assign the text in the edit control TextBoxHwnd to StringX. (Entry of text into TextBoxHwnd is limited to 20 characters.)

My thinking is that since LPSTR is char*, that means that *StringX is a variable of type char. So if I write

code:
char x = *StringX
then I have a single char, x. So I should be able to use the following code

code:
if ( x != '\0' ) {

    // do stuff

}
Apparently not though, this compiles but it crashes the application when it gets to that point.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Are you sure StringX is non-null?

Adbot
ADBOT LOVES YOU

cronio
Feb 15, 2002
Drifter
StringX is uninitialized... you don't actually want an LPSTR (unless you allocate memory for it), you want an array of characters: char StringX[25].

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply