No. All (normal) messages go to a window event handler.
The functions you write to handle events can, of course, be as window agnostic as you like.
No. All (normal) messages go to a window event handler.
The functions you write to handle events can, of course, be as window agnostic as you like.
stty is not the best option for this.
You should first look to see if the environment variable $COLUMNS exists. It is most likely to be correct.
Failing that, use the command tput cols
to query the terminal size.
If you really want to do it properly though you'll have to use ioctl()
with TIOCGWINSZ
.
Hope this helps.
It is not egotistic to simply respond to having one's very simple code roundly abused. The function has the performance and memory characteristics desired when I wrote it. It has no leaks. It does what it is supposed to do. And it isn't filled with convoluted, non-standard stuff.
I've responded to the syntax error you have actually shown me by correcting it, but you have yet to respond by showing exactly how my function has a "logic error" or what all these unnamed "bug"s are. Instead you have resorted to ad homenim by personally belittling my understanding, experience, imagination, and behavior.
Bye.
Looks like a bug to me. Addition of pointers is both nonsensical and illegal in C. I see what the author was going for, but it seems especially awkward. I'd rather just keep a running count of the string length and set
block
to the current null character on each iteration. It's much simpler that way:
You're correct. While addition of pointers is illegal, even if you fixed it, there's still a logic error in that line.
Pointer arithmetic is not illegal. What is illegal is to perform arithmetic on unrelated pieces of memory. The pointer arithmetic was not a mistake; however I could have been more careful to code it as:
block = ok + (size_t)(block - result) - 1;
Since you are in to giving a code review, I'd sure like to know exactly what the logic error is in that line. It seemed me some pretty simple addition for me that kind of error.
Also, I don't think that there is any point in keeping an extra variable around to track information that is already available in (block - result)
. If I were developing under some specific company guidelines that addressed stuff like that I could easily adjust to do just as you would. Otherwise it comes down to nothing more than simple, personal preference.
as i see - this original auther code won't work at all (even without bug about which line we spoke earlier ...
Those are pretty careless statements to …
LINE_MAX is an IEEE extension to the standard <limits.h>, found on some *nix systems. TurboC does is older than, and does not follow, Open Group specifications.
The proper way to do what you want is to use a stack-local variable:
#include <stdio.h>
#include <string.h>
#define MY_MAX 1000
int main()
{
char inputstr[ MY_MAX ];
printf( "%s", "\nPlease enter your input string\n" );
/* Get your input string */
fgets( inputstr, MY_MAX, stdin );
/* Get rid of the trailing newline, if any.
(Notice that this doesn't consider the
possibility that the user input a string
larger than your available buffer. */
char* newline = strchr( inputstr, '\n' );
if (newline) *newline = '\0';
printf( "%s%s%s", "Good job! You entered \"", inputstr, "\"!\n" );
return 0;
}
BUFSIZ is declared in <stdio.h> if you want to use that, but it doesn't really correspond with what you are doing.
The problem with C I/O is that the only safe method is fgets(), but it is a pain to work with directly. There exists the GNU readline library, which helps you with this very easily (and gives the user input editing powers), but if you need you can roll your own simple version, like I did here.
Other issues:
The character ''
doesn't exist. You must specify a value between the quotes. If you want the null character, use '\0'
.
Unless you are doing something very specific, you don't need …
Your professor has actually given you a complete solution -- but his pseudocode is a bit off.
Your function should take only one argument: v - the value to convert to base 3.
Everywhere you see "b" in his pseudocode you should replace that with "3" (because "b" is the base -- your base is 3). (You could, if you desire, add a second argument to the function: b, and use that as the base, then call the function with a base of 3. It is trivial to make the function work either way.)
Inside the function, the first thing you should do (as you have) is calculate k. You have used the second form the professor gave you, since there isn't any log3() function in the standard library. Remember that the logarithm to any arbitrary base "b" can be calculated by dividing the logarithms using another base (for example, base 10) as:
{\bf log}_{3}( v ) = \frac{{\bf log}_{10}( v )}{{\bf log}_{10}( 3 )}
The number k represents the number of digits in the output. Your professor's algorithm uses it to select the bits out of the argument v that are to be printed - most significant to least significant. Most numbers have more than one digit, so you will need to loop through them:
for (; k != 0; k--)
(His pseudocode was not very careful to indicate that there is a loop in there... but if you think about it you …
What version of Delphi/Object Pascal are you using and with what compiler flags/directives?
Why I can't compile without the using namespace std line?
You can, but you have to qualify things.
Things like cout and string and transform() are all defined in the std namespace. If you don't using namespace std (to tell the compiler that all the stuff in std is also in the current namespace) then you must explicitly tell the compiler where to find it.
#include <iostream>
void uses_everything()
{
using namespace std; // import everything from 'std' into current
cout << "everything in std is used here.\n";
}
void uses_cout()
{
using std::cout; // import only 'cout' from 'std' into current
cout << "Only 'cout' was used here.\n";
}
void uses_nothing()
{
std::cout << "Nothing was used.\n";
}
int main()
{
uses_everything();
uses_cout();
uses_nothing();
return 0;
}
There is a second issue here. Make sure that you never using anything in header files.
The file extension on header files has nothing to do with g++, but everything to do with the library author.
The C++ standard requires that certain headers take the form <iostream> and <algorithm> and <cstdio> and the like.
Some people think that was stupid, and use things like ".hpp", as in <boost/any.hpp> and the like.
Some librarys were written in C, or they follow the C convention, and have the ".h" extension, as in "regex.h" and the like.
Just about anything is possible, but most compilers do require you to stick to one of the mentioned conventions.
…If I'm using a Mac, how am I supposed to put a line in the file that contains a '\r' (without it being treated as an EOL)?
Use a std::stringstream:
void Set_Actors(ifstream &fin){
string s;
getline(fin, s);
istringstream ss(s);
for (unsigned n=0; getline(ss, Actors[n], ','); n++){
ss >> ws;
}
}
Notice how I use >> ws
instead of ignore(...)
... it is more robust that way.
Hope this helps.
Fix your indentation and you'll see what is going wrong.
Good luck!
Make your menuFuntion() return whether or not the user elects to continue. So main would look something like:
bool menuFunction();
int main()
{
while (menuFunction())
;
cout << "Goodbye.\n";
return 0;
}
Your exit() function is a dangerous name conflict, especially just to write something before quitting. Hence, you can get rid of it as I have above. (Or just rename it to something consistent, like exitFunction() or goodbyeFunction().)
You might also want to check whether the user entered '9' before asking for the numerator and denominator. "I want to quit." --> "Great! What numerator would you like to use?" Not exactly friendly.
Hope this helps.
On POSIX systems, use poll() (or select()) to check to see if there is user input pending.
On Windows systems, use WaitForSingleObject().
I know this example is for windows, but you can easily modify it to work using the POSIX equivalent (Kubuntu update hosed my system and I haven't fixed it yet, so I'm not going to mess with modifying this example today):
#include <iostream>
#include <string>
using namespace std;
#include <windows.h>
int main()
{
string s;
HANDLE hStdIn = GetStdHandle( STD_INPUT_HANDLE );
cout << "I am going to count to 10.\n"
"Press ENTER at any time to stop.\n";
for (unsigned counter = 1; counter <= 10; counter++)
{
cout << "\r \r" << counter << " " << flush;
// Wait for one second on the standard input.
// If standard input is waiting, we're done.
if (WaitForSingleObject( hStdIn, 1000 ) == WAIT_OBJECT_0)
{
cout << "\r \r> ";
getline( cin, s );
break;
}
}
if (!s.empty())
{
cout << "(You entered \"" << s << "\".)\n";
}
cout << "OK. All done.\n";
return 0;
}
This kind of "is keypressed" function is easy to do:
#include <windows.h>
bool iskeypressed( int ms )
{
return WaitForSingleObject(
GetStdHandle( STD_INPUT_HANDLE ),
ms
);
}
// POSIX
#define INFINITE (-1)
#include <unistd.h>
#include <poll.h>
bool iskeypressed( int ms )
{
struct pollfd pls;
pls.fd = STDIN_FILENO;
pls.events = POLLIN | POLLPRI;
return poll( &pls, 1, ms );
}
On older BSD systems you may have to …
What you want to do is an OS-specific function. What Operating System are you using?
Your professor is a jerk. (Anyone who would instruct his students to do something before doing it himself the same way students would is a jerk.) Using system( "color 1B" );
doesn't work -- that modifies the color of the entire console window.
Since you are on Windows, there are two (good) options to you. The first is to use the Win32 SetConsoleTextAttribute() function like vmanes instructed you. You can set both foreground and background colors with it.
Here is an example program:
#include <iostream>
#include <limits>
using namespace std;
#include <windows.h>
int main()
{
HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
WORD color;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo( hStdOut, &csbi );
for (unsigned f = 0; f < 16; f++)
{
for (unsigned b = 0; b < 16; b++)
{
// On Windows, the color is just this: very easy to calculate.
color = (b << 4) + f;
SetConsoleTextAttribute( hStdOut, color );
cout << " A ";
}
SetConsoleTextAttribute( hStdOut, csbi.wAttributes );
cout << endl;
}
cout << "Press ENTER to quit..." << flush;
cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
return 0;
}
(Clearing the screen is another trick. See here or here for more.)
The other option is to use the Curses library, which is a portable terminal handling library. For Windows versions, check out PDCurses.
Here is a sample program that uses it:
#include <curses.h>
int main()
{
int f, b, color_index;
initscr();
start_color();
for (f …
Hmm, just a good habit I've gotten into. (You just never know when a copy of your object will be used when a reference would have done.)
Stay away from always/never rules. The "Rule of Three" isn't always the right thing to do. In any case, I meant to keep the examples as simple as possible.
You need to specify the standard you are compiling against. The GCC defaults to using its own extensions. g++ -Wall -ansi -pedantic ...
Hope this helps.
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, …
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.
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 …
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.
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.
johnyjj2 if you really want help, please post your code.
What you've listed so far is nonsense.
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.
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.
I agree with AD that the FTP is probably what is going wrong.
FTP defaults to text mode. You must explicitly set it to binary mode before copying files.
The wait() function monitors the state of a process, not its I/O streams. What you really want is the poll() or select() function.
It also seems that you want unbuffered input on your end of the pipe. See termios(3) for more.
See also poll(3) and select(3) for good reading on how these functions are used.
Hope this helps.
In Pascal, a semicolon separates statements (and terminates directives).
So the following is correct:
program Hello; { Semicolon terminates directive }
begin
writeln( 'Hello world!' ) { No semicolon necessary }
end.
As is:
program Hello;
begin
write( 'Hello ' )
; { semicolon separates statements }
writeln( 'world!' )
end.
Since an if then..else block is one statement, there should not be any semicolons between the 'then' and 'else' parts:
if prime( users_number )
then writeln( users_number, ' is prime.' ) { statement not ended }
else writeln( users_number, ' is composite.' ); { now it is at the end }
Even nested ifs must obey:
if foo
then if bar
then baz
else
else quux;
Notice how if foo is true but bar is not, there is an empty statement there (or not there - depending on how you look at it ;) ).
This is the same in code like:
begin
writeln( 'Woah, there are actually TWO statements here.' );
end.
Hope this helps.
I'm sure your instructor has given you much more information than you have given us.
Make sure you review how to open pipes:
man 7 pipe: overview
man 2 pipe: create pipe manual page
And, for good measure, an article on Pipes and filters.
Your professor should have also given you instruction on how to create new processes - whether they be separate programs or simply separate parts of the same program using fork(). (I suspect that your professor has the popen() function in mind -- but I could be wrong.)
Opening and reading a file and writing a new file are both done with the standard fopen() function, as always.
The trick is that your first process will open the file, then write it through the pipe. The second process will read it from the pipe (its own standard input), modify it, and write it to the third process via yet another pipe. The third process opens the target file and writes what it receives from the second pipe (its standard input) to the file.
Hope this helps.
No.
Automatic variables are freed:
int foo()
{
int a = 42;
int* p = (int*)malloc( sizeof( int ) );
*p = a;
return a;
}
Once foo() returns, the automatic variables a (an int) and p (a pointer) are freed, but the heap variable created on line four still exists.
Remember, malloc() creates stuff that has no name. We only have its address (stored in the variable p). By dereferencing p we can access that unnamed value: printf( "%d\n", *p );
Every time you create something on the heap, you must also explicitly free() it.
Here's another example that might help:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p;
p = (int*)malloc( sizeof( int ) );
*p = 42;
printf( "The address of the local (automatic) variable p is %p\n", &p );
printf( "The address of the heap variable is %p\n\n", p );
printf( "The value of the local variable is %08X (%d)\n", p, p );
printf( "The value of the heap variable is %08X (%d)\n", *p, *p );
free( p );
return 0;
}
Notice that p's value is the address (or location) of the heap variable.
Hope this helps.
[edit]
Oh, and a static local variable is just another way of making a global automatic variable. So
int next_foo()
{
static int my_foo = 0;
return ++my_foo;
}
is very much the same as
int my_foo = 0;
int next_foo()
{
return ++my_foo;
}
The only …
>So there's absolutely no way possible for the average person to write to it?
No.
>I was just curious, I absolutely do not want to make any type of virus, trojan, or malware.
Anything that deliberately harms your system is, by definition, malware.
Seriously, you'd get more entertainment by using a sledgehammer or just defenestrating it from some tall office building.
First off, you are being a bit pushy. Stop. Sometimes it takes a day or two to get a (useful) answer.
Secondly, if you can't use C++, then you are posting in the wrong forum.
A good DLL to play around with is C:\WINDOWS\system32\comdlg32.dll. You can use the functions in there. They run the gamut from simple to not-so-simple to use. See http://msdn.microsoft.com/en-us/library/ms645524(VS.85).aspx for complete documentation.
Good luck!
[edit] Most DLLs are not programming language-specific. Those that are are only useful to the application that bundles them. Hence, any DLL ought to do. [/edit]
No.
The kernel is write-protected and you have to know the right magic to get past that.
Deliberately crashing the kernel isn't funny. It is downright dangerous. You can utterly destroy your system and loose data.
It isn't a bug. Free Pascal is a little more strict about certain things than TP.
Your program should read:
program fred;
type funcparam=function(x:real):real;
function jim(x:real):real;
begin
jim:=x
end;
procedure bill(func:funcparam);
begin
writeln(func(3):5:2);
end;
begin
bill(@jim); { Notice that I am getting the address of the function 'jim' }
end.
This will compile properly in TP also.
Hope this helps.
I think you'll have to go ask your professor for clarification. Sorry.
Oh, the bit position is indexed like an element of an array. So if your bits do represent strings (as in vector <string> values;
), then bit zero represents values[ 0 ], bit 1 represents values[ 1 ], etc. A set of those values is then just a number.
(also, I hope you realize that I added spaces in the number for readability: 00 0011 1111 instead of 0000111111).
Your assignment is the kind of exactingly vague description I've come to expect from CS instructors. Do you have an exemplar of the input file? I will assume some things from here on:
A bit string is more commonly called a binary number (integer types).
Hence, the number "10" is the bitstring 1010 (msb to lsb).
For a number, the bits and values are:
{bit 0} = {2^{0}} = 1\\
{bit 1} = {2^{1}} = 2\\
{bit 2} = {2^{2}} = 4\\
{bit 3} = {2^{3}} = 8
etc, so 1010 is 8 + 0 + 2 + 0 = 10.
(Sorry, the LATEX capabilities on the forum are very basic.)
You don't have to associate powers of two with each bit. You can associate other things instead. For example:
"I eat green eggs and ham":
bit 0 = "I"
bit 1 = "eat"
bit 2 = "green"
bit 3 = "eggs"
bit 4 = "and"
bit 5 = "ham"
So the sentence could be represented as 00 0011 1111
(read that from right to left).
Let's add another:
"I don't like green eggs and ham, Sam I am"
bit 6 = "don't"
bit 7 = "like"
bit 8 = "Sam"
bit 9 = "am"
Notice how we didn't need to assign new bits for values that are already associated with a particular bit. The second sentence would then be: 11 1111 1101
. Notice how that …
Complain to your vendor. If their DLL is broken they are obligated to fix it.
Otherwise, read on:
For some oddball reason the C++ design doesn't think that system exceptions belong as part of the exception-handling structure. (Nevermind that every computer hardware has access interrupts, div-by-zero interrupts, etc.)
You need to either:
If you go for number 2, a good place to start is
A Crash Course on the Depths of Win32™ Structured Exception Handling
You will also need the reference.
Good luck!
What version of TP are you using? My TP4 wouldn't get past the 8+ letter filename.
First, you are forbidden to use reserved words as identifiers. That means unit and in are off-limits.
You must then go through and fix all the syntax errors. (Watch the ',' in your write statements, and only the last end should be followed by a '.'.)
Lastly, if you are planning to do what I think you are with that label, don't. Use a loop.
program unitconv;
uses Crt;
procedure do_a_conversion;
var
unit_name: string;
inches, inches_in_feet: real;
...
begin
...
end;
begin
writeln( 'Lytre''s unit converter' );
writeln;
repeat
do_a_conversion;
write( 'Would you like to do another (Y/N)? ' )
until upcase( readkey ) <> 'Y'
end.
Hope this helps.
Argh! I'm so sorry! (Recent med changes have made my brain work worse than usual...)
I forgot a couple of things:
This will work. (I tested it to be sure!)
#include <algorithm>
#include <ciso646>
#include <functional>
#include <string>
struct UTF8_ischar
{
bool operator () ( unsigned char c ) const
{
return (c < 0x80) or (c >= 0xC0);
}
};
std::size_t UTF8_length( const std::string& s )
{
return std::count_if( s.begin(), s.end(), UTF8_ischar() );
}
The above is an optimized version of
std::size_t UTF8_length( const std::string& s )
{
return std::count_if(
s.begin(),
s.end(),
std::bind2nd( std::less <unsigned char> (), 0x80 )
)
+ std::count_if(
s.begin(),
s.end(),
std::bind2nd( std::greater_equal <unsigned char> (), 0xC0 )
);
}
Don't worry too much about the weird stuff. You'll learn about it soon enough. It is just C++'s way of giving the user simple lambda s.
Essentially it says "count every character that has the msb == 0 or the two msbs == 11", which are the UTF-8 prefix codes for individual character sequences [ 1 ].
Sorry again! :$
Have fun now!
Argh, I couldn't find a simple example on the web. So, without further ado:
hello.dpr
program hello;
{$apptype console}
uses greet;
var
index: cardinal;
name: string;
begin
if ParamCount > 0
then for index := 1 to ParamCount do
Salute( ParamStr( index ) )
else begin
Write( 'What is your name? ' );
ReadLn( name );
Salute( name )
end
end.
greet.pas
unit greet;
interface
procedure Salute( name: string );
implementation
procedure Salute;
begin
WriteLn( 'Hello ', name, '!' )
end;
end.
Hope this helps. :)
[edit]
Example use: D:\prog\delphi\hello> [b]hello[/b]
What is your name? [b]Johnny Five[/b]
Hello Johnny Five!
D:\prog\delphi\hello> [b]hello Jacob "Mary Ann"[/b]
Hello Jacob!
Hello Mary Ann!
Yes, it is an encoding issue. I suspect that it comes from the way your editor is saving the text file.
There are several ways to 'encode', or store, character data.
There is the old char-sized ASCII encoding, but that is limited to only 7-bit ASCII characters and any system dependant character codes above 127. Microsoft calls this "ANSI" and the exact selection of extended characters depends on your output code page. Obviously, this is not very convenient for languages using anything but straight-up Roman characters.
Then came (eventually) Unicode, which handles all language graphemes. (This doesn't mean it is complete --additions are still being made, but most industrialized nations can express their native language[s] with Unicode.)
There are several ways to store Unicode: three of which are of interest to us.
UTF-8 uses our venerable char. Only those graphemes that need more than one byte use more than one byte.
UTF-16/UCS-2 variable-width characters, like UTF-8, but where the smallest element is a 16-bit word instead of a byte. This format is considered deprecated, but it is still very much in use.
UTF-32/UCS-4 simply stores every character in a 32-bit word. This is how the GCC treats Unicode (wchar_t) values. As such, modern Linux systems in general are moving toward the exclusive use of this encoding.
So, now that you've had the lecture, on to the point: your text editor is using UTF-8, which you will recall is variable-width. I …
Its full path is given as the first command-line argument. So you will want to add code to check to see if an mp3 file was supplied and autoplay it. How exactly you do it is up to you, but I recommend you read the documentation for TApplication.Initialize.
The following is an example, assuming you have an object named 'MyPlayer' with a method 'PlayFile', etc.
if ParamCount > 0
then MyPlayer.PlayFile( ParamStr( 1 ) );
Hope this helps.
> Maybe even scan the image and set the region pixel by pixel, so we will have a long list of vectorial "lines".
That is actually non-trivial to implement. But there do exist algorithms to do it. I have never had the need (or desire) to try it, so I can't really point you anywhere useful other than Google. (Sorry.)
For simple bitmapped buttons, I will often just use a TImage and the transparent color of the bitmap. If hit-testing is required, the OnMouseDown event can be used to see whether pixel[ X, Y ] is the transparent color or not. That really is the simplest way to do it.
Good luck! :)
I think I understand. You want the actual button itself to have the same shape as the polygon?
You'll have to create a region and assign it to your button.
See the MS Regions documentation.
It isn't particularly hard or even complex, but the trick is knowing how to create the region to begin with.
A GIF or other image is a raster-format: a bunch of lines of pixels.
A region is a vector-format: a list of points that connect lines.
So the trick will be knowing what list of points to use to create the region for each image. You will probably have to spend some time with an image editor to draw lines as an outline around your image and take note of the pixel coordinates of each end of a line. Don't save the changes to the image, but take that list of points and use it to create the regions for each button.
Sorry there isn't a simpler way to do this. The only two options are to have a square button that ignores clicks outside a specific area, or to reshape the button with a region.
Hmm, of course, you could just forget the buttons and use a TPaintBox on the form. Draw all your 'buttons' in the paint box, and when the user gives an OnMouseDown on the form decide whether or not the X,Y coordinate is in any one of the …
I would suspect all that debug code in the VC++ options, and it doesn't look like you have many optimizations enabled either...
Go to your project options and disable debug info and enable all the optimizations you can, and see if that doesn't make a difference.
(I still can't get VC++ to install on my machine... so I can't help more... I just updated to SP3 so maybe I'll get that pesky .NET 3 to work now.)
Good luck!
Take a look in the documentation for the TCanvas.Pixels property. (Your button has a canvas). Also look at the OnMouseDown event.
If I understand you correctly, you need to look in your documentation at SetWindowPos() for the SWP_FOO flags.
Hope this helps.