Duoas 1,025 Postaholic Featured Poster

I've only used these things in Delphi, but it looks right to me.

The only concern I have is based upon your error message:

what kind of thing is OpenDialog1? Is it a pointer to a TOpenDialog? (And not an direct object or a reference?) Is it visible in the current scope where you are using it?

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Sigh. Why is it that C++ questions always degenerate into C questions?

@firstPerson
Your code does not satisfy the OP's requirements. If the OP searches for the word "Hello" in the string "Hello, world!", your code cannot find it because it only delimits on whitespace (which would get the string "Hello," from the file, not "Hello").

You can recover somewhat from this by "trimming" the unwanted characters from the ends of every word you find, but it will not help when you read "one,two,three,four" from the file and wish to find "four".

@FatimaRizwan
If that is not a concern, then firstPerson's solution, plus the "trim" function, ought to be enough to get you going.

If it is a problem, keep reading.

But first, if you want to use C++, please get rid of the C stuff. It will only hurt you later when you fail to learn to do things the right way now.

Granted, this is probably a silly homework assignment, and what follows may be fully ignored. Well, at least I gave it something.


Tokenizing
Even though this is a fairly old concept it is still very much needed and used.

The way that strtok() does it is, shall we say, simplistic. However, we will continue with that model in mind. (Also, I will keep things simple by sticking with the std::string and std::istream data types.)

First, in order to get substrings from a string, …

jonsca commented: Above and beyond! +1
Agni commented: Very helpful code !! +3
Duoas 1,025 Postaholic Featured Poster

Don't use strtok(). It is for handling C-strings (not std::strings), and it modifies the string.

Use the find_first_of() and substr() string member functions instead.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

He has #include <windows.h> , so I believe we can safely assume some things about his operating environment.

On Windows, to wait for an event with a timer, use WaitForSingleObject() with the console input handle specified as the signal object. You'll need to use GetStdHandle().

bool countdown( int& seconds )
  // Displays a countdown timer from 'seconds' downto zero.
  // Returns true if the countdown made it to zero.
  // Returns false if the user pressed a key (which still needs to be read).
  // After the countdown returns, 'seconds' indicates how many seconds still remain to be counted.
  {
  HANDLE hStdIn = GetStdHandle( STD_INPUT_HANDLE );

  cout << "Press any key to abort the countdown.\n";
  for (; seconds; seconds--)
    {
    cout << "\r  " << n << flush;
    if (WaitForSingleObject( hStdIn, 1000 ) == WAIT_OBJECT_0)   // 1 second == 1000 ms
      {
      // The standard input object was signalled, meaning that input is waiting.
      return false;
      }
    }
  // The countdown hit zero. Display that and return success.
  cout << "\rDone!\n";
  return true;
  }

By the way, you should be using ReadConsoleInput() instead of getch()/getchar()/variants.

Also, I just gave you are really big bone. Keep in mind that it is not the whole solution to your homework problem. You still must understand what it is doing and use it properly.

As a hint, your program should be working in a loop to read key presses from the user, and only use the countdown if the user …

Duoas 1,025 Postaholic Featured Poster

To delete files in other directories, you must provide path information.

An absolute path doesn't care where your executable is:

C:\WINDOWS\Media\chimes.wav
/usr/bin/env

(Don't delete either of those, btw.)

A relative path is relative to the current working directory (which may or may not be where your executable is -- it is wherever the user started your program from).

images\snoopy.png
../objs/myprog.o

If you started in (Windows) "D:\MyStuff" then the absolute path would be "D:\MyStuff\images\snoopy.png" or (Unix) "~/myprog/bin" then the path would be "~/myprog/objs/myprog.o".


To delay, use the Sleep() on Windows, or the usleep() function on POSIX.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

^D terminates input. Hence, you cannot read it from the terminal directly (unless you modify the terminal's input state -- which I don't recommend).

If you are sure you are reading from the terminal, you can simply say:

string text;
  cout << "Please enter a bunch of lines. Press Ctrl-D to stop.\n";
  getline( cin, text, char(0) );  // any non-readable character will do
  cin.clear();

Thereafter you can continue to use cin.

Here is a moderately useful little function for you:

#include <cctype>
char Ctrl( char c )
  {
  return std::toupper( c ) - 'A';
  }

You can use it above in like manner: getline( cin, text, Ctrl('D') ); . You can use this version to read from your file too. (And don't forget to clear().)

To write a control character to file, just do:

cout << text << Ctrl('D') << flush;

Just be aware that if you want to read or write a ^M or a ^J to file, it must be opened in binary mode.

Be sure to check to see if you are operating from a terminal (human) or from a device (redirected input), using isatty(), and if it is not a terminal, an EOF really means EOF.

Finally, please be aware that such code will not compile/work on foreign systems (such as Windows).

Hope this helps.

DarkC0de commented: thanks +1
Nick Evan commented: Nice post +12
Duoas 1,025 Postaholic Featured Poster

Wait... are you writing a GUI application or a console application?

To me, MFC Dialog == GUI --> put a "next" button on your form, and don't mess with GetKeyboardState().

Duoas 1,025 Postaholic Featured Poster

Answers like:

Which is equivalent to n = n + 1;

  1. ++n;
  2. n++;

are meaningless. They are the same.

A better answer is:

What is the difference between:

  • x = n++;
  • x = ++n;

Once that is understood then you can get into stuff like avoiding object temporaries for non-native types. (See the C++FAQ-Lite.)

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Hi all. I've nearly finished the home page for my wife. Sadly, I've discovered (again, surprise, surprise) IE doesn't play fair.

I wanted the home page to be a simple "splash with links" kind of thing, and I used a variation of Meyer's CSS popup technique to do it. (See this and that.)

This is what it should look like, followed by the stuff I get in other browsers:
[img]http://home.comcast.net/~mlyn7576/temp/ff-opera.png[/img]
[img]http://home.comcast.net/~mlyn7576/temp/ie6.png[/img]
[img]http://home.comcast.net/~mlyn7576/temp/safari.png[/img]

This is the HTML for the links:

<div align=center class="menu nobreak">
      <div class="menu-top-spacer"></div>
      <a
        id="menu-1" href="benefits.html"><span>Why Sign?</span><span id="menu-text-1">

          Using American Sign Language <br>
          with your children has many  <br>
          <b>Benefits</b>. &nbsp; Learn more...

          </span><img id="menu-image-1"></a><span class="hide">&nbsp;&nbsp;&nbsp;</span><a
        id="menu-2" href="melissa.html"><span>Melissa</span><span id="menu-text-2">

          Just who am I anyway?

          </span><img id="menu-image-2"></a><span class="hide">&nbsp;&nbsp;&nbsp;</span><a

            ...and so on...

          </span><img id="menu-image-5"></a>
    </div>
  </div>

And this is the CSS:

.menu
  {
  position:             relative;
  padding:              0px;
  margin:               0px;
  background:           url("images/menu.gif") no-repeat 0px 0px;
  width:                755px;
  height:               54px;
  text-align:           left;
  }

.menu span,
.menu img,
.menu a img,
.menu a span
  {
  border:               0px none;
  display:              none;
  visibility:           hidden;
  }

.menu-top-spacer
  {
  padding:              0px;
  margin:               0px;
  height:               19px;
  }

.menu a
  {
  display:              inline-block;
  top:                  19px;
  height:               25px;
  }

.menu a#menu-1
  {
  background:           url("images/menu.gif") no-repeat 0px -19px;
  width:                153px;
  }

/* ...and so on... */

.menu a:hover
  {
  border:               0px none;
  }

.menu a:hover span#menu-text-1,
.menu a:hover span#menu-text-2,
.menu a:hover span#menu-text-3,
.menu a:hover span#menu-text-4,
.menu a:hover span#menu-text-5
  {
  display:              block;
  visibility:           visible;
  position:             absolute;
  bottom:               81px; …
Duoas 1,025 Postaholic Featured Poster

Ah, perfect. Hopefully that is all there is to it. Thank you!
(Once it gets up on the webserver I'll test again.)

Duoas 1,025 Postaholic Featured Poster

Hi all.

I am designing a website for my wife's business, and I am coding it by hand -- pure HTML 4.01 Strict and CSS-1.

When I loaded it into IE 6 (6.0.2900.5512.xpsp_sp3_gdr.090804-1435) I got a message complaining that it had "Active Content". (I am aware it is a result of Eolas's lawsuit.)

I'm not too knowledgeable about all the bells and whistles you can add to a web page, but I am pretty darn certain that I have not added anything that can be reasonably considered "active content".

Which leads me to ask: what kinds of things does MS mean by "Active Content"? All I can find on the web is references to animated GIFs, ActiveX plugins, DHTML, etc -- which I have explicitly not placed on her site. Currently, the site is executing right off my own PC (as one HTML file and one CSS file loaded directly into the browser).

Again, all it has is HTML 4.01 Strict and CSS-1 content, with a couple of old-style tags ('bgcolor' and 'align') to make it downgrade gracefully in old browsers.

Please point me in the right direction to figure out what is causing this abnoxious message.

Thank you!

Duoas 1,025 Postaholic Featured Poster

Nice!

Duoas 1,025 Postaholic Featured Poster

Do you mean like

rd /q/s C:\DOCUME~1\John\Cookies
rd /q/s C:\DOCUME~1\Jill\Cookies
rd /q/s C:\DOCUME~1\Johann\Cookies

?

Duoas 1,025 Postaholic Featured Poster

It is always great to give a nice, complete example and to be completely ignored not only at the time the example was given, but also a full year later.

Duoas 1,025 Postaholic Featured Poster

Keep in mind that this is useful only for homework problems or other simple software.

If you are writing commercial software, or secure systems, you should know better than to use this, as it is resource heavy and it is a huge, gaping security hole.

Perhaps I should post an update for how to do this the Right Way.

Duoas 1,025 Postaholic Featured Poster

First off, C++ does not know anything about the I/O device you are using. It can be a keyboard and monitor, or a file, or a network connection, or anything which can do I/O. What that means is that there is no standard way to do this in C++.

That said, the following should work on any Unix/Linux platform and on any version of Windows. That's because it cheats by using another program to clear the screen.

All Unix/Linux systems have a command line program called "clear" which clears the screen.
Likewise, all Windows systems have a command line command called "cls" to do the same.

This works by first trying one, and if that doesn't work, then using the other. The order in which they are tried does not matter.

Duoas 1,025 Postaholic Featured Poster

Keep in mind that this is useful only for homework problems or other simple software.

If you are writing commercial software, or secure systems, you should know better than to use this, as it is resource heavy and it is a huge, gaping security hole.

Perhaps I should post an update for how to do this the Right Way.

Duoas 1,025 Postaholic Featured Poster

First off, C does not know anything about the I/O device you are using. It can be a keyboard and monitor, or a file, or a network connection, or anything which can do I/O. What that means is that there is no standard way to do this in C.

That said, the following should work on any Unix/Linux platform and on any version of Windows. That's because it cheats by using another program to clear the screen.

All Unix/Linux systems have a command line program called "clear" which clears the screen.
Likewise, all Windows systems have a command line command called "cls" to do the same.

This works by first trying one, and if that doesn't work, then using the other. The order in which they are tried does not matter.

Duoas 1,025 Postaholic Featured Poster

Nice, but it fails on three counts:
1. It doesn't return the new head of the list.
2. It fails if h is NULL.
3. It fails on really big lists (stack overflow).

Here's an iterative solution you might enjoy.

/*
  Reverse a singly linked list without recursion.
  The argument may be NULL.
  Returns the new head of the list.
  Runs in linear time and with constant memory usage.
 */
node *rev( node *head ) {
  node *next;
  node *curr = head;
  node *prev = NULL;

  while (curr != NULL) {
    next       = curr->next;
    curr->next = prev;

    prev       = curr;
    curr       = next;
    }

  return prev;
  }

Call it thus: head = rev( head ); Enjoy!

Duoas 1,025 Postaholic Featured Poster

Nice. The only problem is that you can have overflow, which would destroy the values of the variables. Use bitwise operations instead:

a ^= b;
b ^= a;
a ^= b;

Enjoy.

Duoas 1,025 Postaholic Featured Poster

I know this is old, but anyway...

I've always preferred a simple variation of bar():

unsigned char rev( unsigned char b ) {
  unsigned char result = 0;
  while (b) {
    result <<= 1;
    result  |= b % 2;
    b      >>= 1;
    }
  return result
  }

This method has the nice property that it is 100% portable.

Duoas 1,025 Postaholic Featured Poster

It is because you have misunderstood something.

A string is not a simple POD type -- it is an object type -- which you cannot write directly to file (according to Delphi standards [and also ISO standards, but that's beside the point ;) ]).

The write[[b]ln[/b]] functions know how to transform a string into a simple sequence of characters.

They do not know how to handle your thing type, because it has a non-POD member (the string).

When you create file types, they must be sequences of non-object types. Hence, type tFooFile: file of string; fails, where

type
  string80: array[ 1..80 ] of char;
  tFooFile: file of string80;

succeeds.

What you can do is write procedures/methods that know how to write your non-POD type to a given file, then call it when you wish to write it.

For more information, google around "delphi or pascal object serialization".

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

I suggest you take a read through The Function Pointer Tutorials, particularly this one.

I would use some typedefs to help:

typedef float (char2float_t)( char );
typedef char2float_t* int2char2float_t( int );

...

char2float_t* wonky_function_1( int n )
  {
  ...
  }

...

int2char2float_t* fp1 = &wonky_function_1;

char2float_t* fp2 = fp1( 42 );  /* or: fp2 = (*fp1)( 42 ); */
float value = fp2( 'A' );       /* likewise: value = (*fp2)( 'A' ); */

BTW, you really are doing something weird. What goal can you possibly be trying to accomplish? (It appears to me that there is a design flaw in your program.) Perhaps we can suggest something better (and easier).

Also, this is the C forum. You are using C++.

Salem commented: Excellent stuff +36
Duoas 1,025 Postaholic Featured Poster

If you have actually fork()ed (or spawn()ed) a child process, and you just want to check whether or not it has terminated, you want the waitpid() function.

You can also use the usleep() function to cause the parent to spin its wheels for a short bit. There are more modern and/or better ways to do this, but this is short and simple...

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
...
int status;
int seconds = 0;
do {
  /* Pause for a second */
  usleep( 1000000 );
  /* Tell the user the number of elapsed seconds */
  printf( "\r%d seconds...", ++seconds );
  /* Check the child's current status */
  waitpid( (pid_t)(-1), &status, WNOHANG );
  /* Only break if it has terminated */
} while (!WIFEXITED( status ));

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

A std::vector is guaranteed to maintan contiguous data space -- meaning it cannot handle really large data.

Use a std::deque instead. I looks much the same, but the data need not be stored contiguously -- meaning it can handle a great deal larger amount of data (because it can work with the OS/compiler's memory management more flexibly).

BTW, you shouldn't be using atoi(). Use a stringstream instead...

#include <sstream>
#include <stdexcept>
#include <string>

int myatoi( const std::string& s )
  {
  int result;
  std::istringstream ss( s );
  ss >> result;
  if (!ss.eof()) throw std::runtime_error( "not an integer" );
  return result;
  }

Untested!

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

There is no simple answer.

You might want to look through The GUI Toolkit, Framework Page.

TrollTech Qt is a good choice if you can use it -- it has some powerful image handling capabilities.

GTK+ is also a very good choice for image handling.


IDE's like VB's are a different thing. MSVS is similar -- it will allow you to drag-and-drop yourself a user interface. If you plan to use this route, you might want to look just for a C/C++ imaging library you can use to manipulate the images in your program.

I'm sure others here might have better suggestions. Nevertheless, I hope this helps.

Duoas 1,025 Postaholic Featured Poster

You should read up on virtual methods.

class Greeting
  {
  public:
    // Here is our abstract, overridable method
    virtual std::string hello() const = 0;
  };

// Here is an example of how it is used
class Saludo: public Greeting
  {
  public:
    std::string hello() const { return std::string("Buenos Dias"); }
  };

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

You don't need to use strcat()... Please don't suggest using the C string library to manipulate C++ strings.

AD already addressed your question. You should be using getline() to get user input:

string dirpath;
getline( cin, dirpath );  // gets everything, including spaces

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

The first thing you need to do is break your dependence on the system() function. It spawns a new shell (cmd.exe, probably), changes the directory for that new shell, then terminates. Your program's current working directory remains the same.

Most C/C++ compilers provide versions of the <unistd.h> function chdir().

You can get information about the files in the directory using opendir(), etc. in <dirent.h>, and stat() in <sys/stat.h>. For all these, you'll also have to #include <sys/types.h>.

If you want to do it the Microsoft Windows way, you'll have to #include <windows.h> and use SetCurrentDirectory() and the FindFirstFile()/FindNextFile() functions.

Good luck!

Duoas 1,025 Postaholic Featured Poster

Sorry I was so grouchy.

iamthwee commented: get some R and R baby. +22
Duoas 1,025 Postaholic Featured Poster

There are differences in the make between POSIX and Windows, as well as some problems with the MSYS make (which is POSIX, AFAIK).

You should be using your ~MinGW\bin\mingw32-make.exe program when compiling in the non-POSIX (Windows native) environment, and the ~MSYS\...\bin\make.exe program when compiling under the MSYS POSIX environment.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Well, Hiroshe, since your brain power is obviously so much greater than mine, the answer to your input question is simply: you've already figured it out.

Writing portable code has nothing to do with avoiding system dependencies. Rather, it has everything to do with how your code is bound to those dependencies.

But, since you so knowingly disagree, you can continue without me.

Duoas 1,025 Postaholic Featured Poster

johnyjj2 if you really want help, please post your code.

What you've listed so far is nonsense.

Duoas 1,025 Postaholic Featured Poster

Standard C doesn't have any concept of console or graphics displays. Hence, what you are trying to do is technically impossible.

If you are using a graphics library then you should be able to get unbuffered keyboard input from it.

Otherwise, how are you doing the pong game in console? Whatever library you are using should have a way to get unbuffered keyboard input.

Every display and every computer system is different. Libraries like NCurses are written to help mitigate those differences, but they ultimately are OS/hardware bound. There is no such thing as a standard C display.

Turning off buffered-input and echo is really not that difficult to do, nor is polling the keyboard for any ready input.

All we want to know is: system/OS for each target.
Then we can point you in the right direction for the necessarily OS-dependent methods to do what you want.

Holding down a key to keep the program running is, IMO, not a good design decision.

Duoas 1,025 Postaholic Featured Poster

Wow, look a gift horse in the mouth...

If the library that ships with your OS isn't sufficient, or you want something portable (which <conio.h> isn't, BTW), try NCurses.

For Windows: http://pdcurses.sourceforge.net/
For POSIX: http://www.gnu.org/software/ncurses/
Getting started: http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/

Duoas 1,025 Postaholic Featured Poster

It would, as VernonDozier suggested, be easy enough to code your own version...

Here's a simple stab at it:

#include <iostream>
#include <string>

std::istream& getline( std::istream& ins, std::string& result, const std::string& terminator )
  {
  char c;
  result.clear();
  while (ins.get( c ))
    {
    result.push_back( c );
    if (result.rfind( terminator ) == (result.length() - terminator.length()))
      {
      result.resize( result.length() - terminator.length() );
      break;
      }
    }
  if (result.length()) ins.clear();
  return ins;
  }

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

I suggest SDL.
Take a look through Lazy Foo' Productions's tutorials to get started.

There is also PyGame, which uses Python...

Good luck!

Duoas 1,025 Postaholic Featured Poster

Whitespace between the keyword end and the period is not significant.

Perhaps you should post more code? It is hard to diagnose what is wrong.

With FPC, you must be sure to have the {$goto on} directive enabled.

I don't think that the $N directive is used in FPC -- the FPC uses native floating-point types -- there is no need to ask for them or emulate them.

Duoas 1,025 Postaholic Featured Poster

Standard C doesn't have anything to do with it.

You need to modify the input stream's mode to "unbuffered". You probably want to turn off "echo" also.

Both of these things are OS-dependent things to do. What OS are you targeting?

Duoas 1,025 Postaholic Featured Poster

Check out the <csetjmp> library.

Don't mess with the stack. Otherwise you invite death.

Duoas 1,025 Postaholic Featured Poster

The GCC does not supply gotoxy() with <conio.h>.

Since it is a Windows program, why not use the SetConsoleCursorPosition() function?

If you are using POSIX, let me know.

Duoas 1,025 Postaholic Featured Poster

Unfortunately I never did have much time to sink into it, so I never did figure out what caused it. I still think it has to do with memory paging or something...

I just optimized the tar out of the code so it works fast enough to respond reasonably snappy... (The optimization was something of a design decision at the outset, so I didn't waste too much time with it.)

Sorry I just don't know right now.

Duoas 1,025 Postaholic Featured Poster

In both instances you are misusing the GetCDHandle() function.

The function takes a pointer to an extant GETCDHAND struct.

HCDROM    hcd;
GETCDHAND cdhand;
hcd = GetCDHandle( &cdhand );

Hope this helps.

[edit] There might be other errors too... but I've got to go now [/edit]

Duoas 1,025 Postaholic Featured Poster

Sigh.

#include <algorithm>   // remove_if()
#include <cctype>      // isspace()
#include <functional>  // ptr_fun <>
#include <iostream>    // I/O
#include <string>      // string
using namespace std;

int main()
  {
  cout << "Space remover.\n\n"

          "Please enter strings with spaces.\n"
          "Enter a blank line to quit.\n\n"

          "> "
       << flush;

  string s;
  while (getline( cin, s ) && !s.empty())
    {
    s.erase(
      remove_if(
        s.begin(),
        s.end(),
        ptr_fun <int, int> ( isspace )
        ),
      s.end()
      );
    cout << s << endl << string( s.length(), '-' ) << endl;

    cout << "\n> " << flush;    
    }

  cout << "Bye.\n";
  return 0;
  }

See lines 21 through 28. Replace the isspace() function with one of your choosing.

Is this thread one of those that is going to be resurrected once a year forever more?

Duoas 1,025 Postaholic Featured Poster

Sorry to respond to this late... but I wanted to post info also...

The getline() function has the obnoxious habit of returning a not good() stream for final blank fields...

For a single blank line at the end of input, that's fine... (there's no record) but for blank fields it makes a difference. You can get past the problem by checking the stream state before getting a line.

For simple CSV files (meaning you cannot use the ';' character [or whatever character you've chosen] in the field value) this is a working example:

#include <deque>
#include <iostream>
#include <sstream>
#include <string>

typedef std::deque <std::string> record_t;
typedef std::deque <record_t>    table_t;

std::istream& operator >> ( std::istream& ins, table_t& table )
  {
  std::string s;
  table.clear();

  while (std::getline( ins, s ))
    {
    std::istringstream ss( s );
    record_t           record;
    std::string        field;
    bool               final = true;

    while (std::getline( ss, field, ';' ))
      {
      record.push_back( field );
      final = ss.eof();
      }
    if (!final)
      record.push_back( std::string() );

    table.push_back( record );
    }

  return ins;
  }

This will allow you to read all seven fields in a record like:

one; two;three;four;;six;

Hope this helps.

Ancient Dragon commented: Great example :) +36
VernonDozier commented: Haven't seen you in a while. Nice post. +19
iamthwee commented: welcome back blender man +22
Nick Evan commented: Nice :) +22
Duoas 1,025 Postaholic Featured Poster

It is easy enough with the mouse events.

The MouseMove event handler should do something like the following pseudocode:

procedure TFooey.MouseMove( ... );
  begin
  if (nothing prevents you from responding to normal hovering)
    then if (x and y are in the object''s area)
           then begin
                if hover_mode <> hover
                  then begin
                       hover_mode := hover;
                       SetCaptureControl( TControl( self ) );
                       paint;
                       invoke_custom_rollover_event_hander
                       end
                end
           else begin
                if hover_mode <> not_hover
                  then begin
                       hover_mode := not_hover;
                       ReleaseCapture;
                       paint
                       invoke_custom_rollout_event_handler
                       end
                end;
  invoke_custom_mouse_move_event_handler
  end;

If you are doing this for TGrid components, you will also want to track not just the hover state, but also which cell is currently being hovered, if any.

Hope this helps.

Duoas 1,025 Postaholic Featured Poster

Unfortunately, there really isn't a very amazing way to do directory browsing natively.

That aside, there is also useful information like this:
Centering the Select Directory dialog at about.com.

Enjoy!

Duoas 1,025 Postaholic Featured Poster

You are looking at the form resource data. Essentially, when the original program was written (in Delphi), the programmer used a TImage component in the forms designer, double clicked the Picture property in the Object Inspector, and Loaded a bitmap file (or anything else his Delphi was able to load) and stored it in the DFM file.

You can replace the image easily by starting a New Application (Win32 -- not console or anything weird), dropping a TImage component on the form, then populate the image from file. By default Delphi takes Microsoft BMP images (so your replacement image should be saved as a 24-bit BMP file). Load it so that it is displaying in the IDE on the form. Save all.

Now, go find your form's DFM file. Find the image object. It starts with the word 'object' and ends with the word 'end'. If you left all names at the default, it will look something like this:

object Image1: TImage
    Left = 136
    Top = 234
    Width = 18
    Height = 18
    Anchors = [akLeft, akBottom]
    Picture.Data = {
      07544269746D617026020000424D2602000000000000BE000000280000001200
      000012000000010008000000000068010000120B0000120B0000220000002200
      0000A4A7A400CFCFCF00D0D0D000D1D1D100D2D2D200D3D3D300D4D4D400D5D5
      D500D6D6D600D7D7D700D8D8D800D9D9D900DADADA00DBDBDB00DCDCDC00DDDD
      DD00DEDEDE00DFDFDF00E0E0E000E1E1E100E2E2E200E3E3E300E4E4E400E5E5
      E500E6E6E600E7E7E700E8E8E800E9E9E900EAEAEA00EBEBEB00ECECEC00EDED
      ED00EEEEEE00EFEFEF0000000000000000000000000000000000000000002121
      2121212121212121212121212121212100001F20202020202020202020202121
      2121212100001D1D1D1D1D1E1E1E1E1E1E1E1E1E1E1E1F1F00001B1B1B1B1B1B
      1B1B1B1C1C1C1C1C1C1C1C1C0000181819191919191919191919191A1A1A1A1A
      0000161616161616171717171717171717171718000014141414141414141414
      1515151515151515000011111112121212121212121212121313131300000F0F
      0F0F0F0F0F101010101010101010101000000D0D0D0D0D0D0D0D0D0D0D0E0E0E
      0E0E0E0E00000A0A0A0A0B0B0B0B0B0B0B0B0B0B0B0B0C0C0000080808080808
      0808090909090909090909090000050606060606060606060606070707070707
      0000030303030304040404040404040404040405000001010101010101010102
      0202020202020202000001010101010101010101010101010101010100000000
      000000000000000000000000000000000000}
    Visible = False
    ExplicitTop = 230
  end

Copy the stuff for the Picture.Data (lines 7 through 25 in my example image above). Depending on the size of the image you added, it could be a pretty long listing. Make sure you get it all.

As you've already noticed, …

Duoas 1,025 Postaholic Featured Poster

No, it isn't solved. Wait until it is. ;-)

Duoas 1,025 Postaholic Featured Poster

Eh, why not?

uses SysUtils, Windows;

procedure TypeStr( lpszString: pChar );
  var
    cChar: char;
    vk:    word;
  begin
  cChar := lpszString^;
  while cChar <> #0 do
    begin
    inc( lpszString );

    vk := VkKeyScan( cChar );
    if ((vk shr 8) and 1) <> 0 then keybd_event( VK_LSHIFT, 0, 0, 0 );
    keybd_event( vk and $7F, 0, 0, 0 );
    keybd_event( vk and $7F, 0, KEYEVENTF_KEYUP, 0 );
    if ((vk shr 8) and 1) <> 0 then keybd_event( VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0 );

    cChar := lpszString^
    end
  end;

Enjoy.