ExplainThat 1 Junior Poster in Training

Perhaps, I haven't fully understood your question but it seems to me that you are going about things in a somewhat complicated way. Firstly, by far the neatest way to add entries to a list view goes something like this

  • Use the ListView.Items.Add method to add a new row
  • Assign the "Caption" property for that row
  • Use the SubItems.Add method to add the other column entries

Once you have done this there remains the sorting issue. TListView offers an OnCompare event that is supposed to help with the task of custom sorting. In practice it is badly bugged and the results are rarely satisfactory. A better approach is to do the following

  • Assign an OnColumnClick event handler
  • In that handler call the CustomSort method of the list view.
  • You need to provide a callback function to CustomSort to establish list order. There is adequate information in the Delphi help file on this subject
ExplainThat 1 Junior Poster in Training

Your best long term bet would be to start using the TNT component suite. It is no longer freeware but you can still get an updated version of the last freeware version here

TNT Controls

By and large TNT controls are a drop in replacement for the equivalent Delphi ones. If you have already got a number of forms with the "normal" controls here is a quick and easy way to do the conversion

  1. Install the TNT component suite
  2. With each form in your project hit Alt + F12 to see the DFM code.
  3. Now systematically replace T* with TTnT* where * is Label, Edit, Memo etc.
  4. Hit Alt + F12 again to see the form designer.
  5. Save the form. At this point Delphi will prompt you to correct the control declarations - e.g. from Label1:TLabel; to Label1:TTnTLabel.
  6. Just keep saying Yes till you are all done

Compile and enjoy! Couldn't be easier! Apart from that you might occasionally need to draw text directly using the DrawTextExW Windows GDI function call.

Hope this helps.

ExplainThat 1 Junior Poster in Training

A print-ready MySQL quick reference is available <URL SNIPPED>. Registration (free) is required for access to a more legible version.

An extended version of this card that covers the MySQL SQL dialect in detail is in the works.

Enjoy!

ExplainThat 1 Junior Poster in Training

All very valid points - I haven't browsed to your page and checked the actual download time so it could well be that you are starting of with unreasonable expectations.

As others have pointed out - a webpage that goes on and on and on is not a good idea. Yours certainly does. There is also an issue with tables - browsers need to get the full content of a table before they start rendering it on screen since they are unable to make the requiste layout calculations on-the-fly as they get page code. You have stuck a great deal of your content inside table(s). Tables are completely passé. They have a use - for tabular data - but display layout is not it. Consider using a CSS driven layout, make good use of divs... .

All that - and make sure you start of with reasonable expectations and good content design in the first place.

ExplainThat 1 Junior Poster in Training

Hi, I was wondering, if it is possoble (or how to) include a php file with a get form value passed.

For Example: states.php?state=NY.

This file would be incuded into another php file so that it would display only the items that would be in NY state.

Anyone know how to do this??

Help is greatly appreciated.

There are probably several ways of accomplishing this. One would be to simply use file_get_contents to load the file text into a string and then do whatever you like with it.

Not sure just why you want to do things this way. At the very least you should sanitize the user input so you don't end up squirting back sensitive files. For instance someone might try to browse to

states.php?state=.htaccess or states.php?state=mybusinessdata.db

ExplainThat 1 Junior Poster in Training

Wow! With a code listing like that it is scarcely surprising that you have got no replies. I haven't read all your code - and chances are no one else will - but here is, I hope, a partial solution

1. You appear to have a great deal of CSS and JavaScript embeded in your HTML. Put this in separate files and use links to those files instead. Then, assuming you are serving up from Apache, create the following .htaccess file in the directory from which you serve up the .css and .js files

ExpiresActive On
ExpiresByType text/css A8640000
ExpiresByType text/js A8640000

This ensures that when the document in question is revisited the browser does not end up reloading CSS and JS that has probably not changed. Here we are setting an expiry date 10 days (86400s x 10) from the time the file was accessed. You should only do this once you are reasonably certain that you have a final version for your CSS and JS. If after that point you are obliged to make changes simply change the name of the external CSS/JS file in question.

2. The above will help but not by much. You should also compress both your CSS and your JS. You will find two rather nice online compressors here

CSS Compressor
JavaScript Compressor

The Dojo JavaScript compressor is very good but your JS needs to follow certain conventions - e.g. the ; is obligatory …

ExplainThat 1 Junior Poster in Training

A few weeks ago I was in the same situation and I would recommend the following books:

  • PHP MySQL Web-Development All-in-One-Desk-Reference For Dummies
  • PHP5 and MySQL Bible / By: Tim Converse and Joyce Parks, with Clark Morgan.

Also the following google search term:
site:www.php.net mysql
Note that the link above was computer generated so make that entire line a search term.

And also use PhpMyAdmin to generate some MySQL query's but you will need to alter those computer generated query's. And of course there is the following web link:
http://www.tizag.com/mysqlTutorial/

Tizag is a good place to begin. However, PHP is an unimaginably huge beast so beyond a certain point you will have no choice but to use the php.net online documentation. The quality of this documentation is perhaps one of the best arguments for choosing PHP as opposed to another server side scripting language.

I have a, free and print-ready, PHP cheatsheet here which you may find useful.

ExplainThat 1 Junior Poster in Training

Sheady,

It is never very easy pinpointing errors based on very long code listings such as yours. Having taken a brief look at your code I have several suggestions to make

  • In my book any object procedure that exceeds around 20 lines of code needs to be broken up into multiple function/procedure calls.
  • You are handling several distinct tasks in your code so you could do that quite easily - and it will result in more readable code.
  • Are you aware of the with keyword? You might be able to use it to good effect here to write code that is easier to read and to maintain
  • Doing file operations without a try..except block to handle the unexpected is very unwise. At the very least you should have that.
  • ReSet returns an error in IOResult which might do with checking when the unexpected does happen
  • You might be better of doing one of the following in place of your AssignFile, ReSet... code
  1. Read the file into a TStringStream or a TStringList
  2. Check that the file exists using FileExists
  3. If the path to your file is being generated by code make sure that the path is correct by outputting it to DebugView - or a message box if you don't feel upto DebugView
  4. Finally, when things go wrong in code such as yours and logic does not help sort out the problem it is useful to follow a "divide and rule" strategy - systematically comment out portions of …
ExplainThat 1 Junior Poster in Training

Hmmm... Apache is a heavyweight solution. I suggested Abyss cos it does the job and is so easy to administer.

ExplainThat 1 Junior Poster in Training

No He don't! He is experienced web designer. May be I'm the one who misunderstood Him, for I'm newbie with little knowledge of html. So where do I start sir? HTML,XHTML, CSS or what?
I want to become web as well as application programmer. I'M doing well in python but not much in web! I have also failed to run my script offline my firefox through abyss. Help please!!

Steve:(

Steve,

Here are a few general tips

  • Pick a subject you enjoy to create your first site. That improves your chances of actually doing a good job with it
  • Pick a decent domain name but don't let that become too much of an obsession. A great domain name with no content worth speaking of is of no use.
  • Pick a decent host for your site. The one recommended by this forum is not a bad one though their pricing + service are far from being the best around.
  • When picking a host make sure they allow you to run PHP5 scripts.
  • Create a simple functional site using XHTML + CSS, get it launched and make sure you tell the search engines about it. It takes time for SEs to index your site and then serve it up in search results so no point waiting to launch until you have every last bit in place - it will never happen anyway.
  • Use the SHTML or PHP extension on all your web pages. This makes it easier to make …
ExplainThat 1 Junior Poster in Training

Hello here!
I'm newer new to PHP. I haven't even started. What softwares and tools and Books that I need to start? I love simple web programming! One friend told me it is easier with XHTML and CSS but there is no place here for that Langueage. I think I need to study PHP!

Help please!
Steve :)

Your friend is misleading you. XHTML, CSS and PHP are not somehow mutually exclusive. You can get so far with client side technologies - such as HTML, CSS and JavaScript - and then find that you need to do some smart stuff on the server side to really make your site stand out. That is where PHP comes in. You can actually do a great deal without launching into PHP by making good use of SSI (Server Side Includes) but they are no substitute for a real server side scripting language. All that said, here are some useful links

The official PHP site with documentation, downloads and more
Has online tutorials covering the basics of PHP
A printable quick reference guide covering basic PHP

It might also be a good idea to join a good PHP forum e.g. PHPFreaks.

Apart from this you also need to test your PHP code locally. A simple way to do this is to install the Abyss webserver along with their preconfigured PHP 5.2 package on your machine. You will find everyting you need …

ExplainThat 1 Junior Poster in Training

Or may be i divide program to some dll file that contain form and function?

Brief answer is take a look at using interfaces. In case you are not familiar with the concept

  1. An interface is used to declare an intent to provide certain services
  2. By services I mean methods and properties
  3. Having defined your interface(s) you must create classes that implement the interface(s)
  4. You have a choice of starting with TInterfacedObject or TCOMObject - an oversimplification but enough to get you started
  5. Delphi does not support multiple inheritance - fortunately - but you can get a classs to implement more than one interface

Just how easy or hard this is depends on how you see your project growing. If you merely want flexibility for your own future needs it can be quite simple. If on the other hand you want to provide a well documented API that others will be able to plug into and extend you will need to do more work.

ExplainThat 1 Junior Poster in Training

Nice. :)

Thank you!

ExplainThat 1 Junior Poster in Training

A cheatsheet covering the core features of PHP 5 is available here

PHP5 Cheatsheet

Free to print, share and enjoy.

ExplainThat 1 Junior Poster in Training

A very simple obfuscation may make it not worth the effort for the magpie types - try this

http://javascriptcompressor.com/

It is a freebie.

ExplainThat 1 Junior Poster in Training

You should consider redesiging so you don't use popup windows - chances are the user's browser will block it. Consider creating a popup effect using CSS + HTML instead.

ExplainThat 1 Junior Poster in Training

There are two ways to handle error

  • onerror - which just allows you to carry on gracefully when there is an error but takes little corrective action
  • The try..catch code block that allows you to trap the error and deal with its consequences

I discuss this, and many other JS issues, in my quickreference guide

JavaScript Quick Reference

Hope this helps.

ExplainThat 1 Junior Poster in Training

I think the right answer here is - don't bother. Wanting to hide CSS, HTML and JavaScript is

  1. difficult if not impossible
  2. quite against the spirit of the web - at one time or another we have all benefited from looking at other peoples' code so you shouldn't complain when it is payback time

Sure there are times when you want to keep all and sundry from knowing how you do certain things. When that is the case consider doing one of the following

  • Use server-side logic do to all that is needed.
  • Use the XMLHTTPRequest object along with the JavaScript eval function to have the code downloaded and executed on the fly. This does not "protect" it but does make it a lot less accessible.
ExplainThat 1 Junior Poster in Training

Hi well ive got school project and well found this site looks like real deal not like the fake ones ive registered 2 and this site can really help?...

Well ive done most of my programmeing just cant figure the search code i cant get.....

I need to say type in keyword in the edit...then when i press a button it searches the keyword list(Database imported from acces onto DBgrid) wich is in dbgrid the files are.

basicly to type word in and when press search display everything that is beside that keyword?..

can anyone help me out? or just give me snippets that will help alot thanx..

and glad to be here :) Looks like awesome place

Petez, I am guessing that English is not your first language. I am not sure which other forums you posted to. However, it is possible that - as with this forum - you have not got a response because your question does not make any sense. Try again, provide an explanation that is both clear and concise - I am sure someone will help out.

ExplainThat 1 Junior Poster in Training

Yes, but I don't often find time to survey more than one forum here. Try posting to the VB.NET forum - someone is bound to help out.

ExplainThat 1 Junior Poster in Training
program array_sum;
Uses wincrt;
var
   nums:array[1..10] of integer;
   index:integer;
   Sum:integer;
Begin
     sum:=0;//Delphi initializes local variables. Not sure if your Pascal compiler does
     index:=1;
     writeln('Input marks');
     while (index<=10) do
           Begin
                Readln(nums[index]);
                sum:=sum + nums[index];
                //you can update sum in the input loop - no need for a separate loop
                index:=index+1;
           end;
     writeln('sum',sum);
end.

As a general observation for loops are more efficient - if you know you are working with 10 inputs. If this number is liable to be variable you might need to put in a test for an invalid input and break out of the loop prematurely. In any case, I would suggest some means of allowing for a premature break.

Better use a variable name other than Index - if it clashes with an object property that is in scope, for instance, you can end up with a hard to trace bug.

ExplainThat 1 Junior Poster in Training

Not sure why you have two integer variables x and Counter. Surely, you could work with Counter alone, couldn't you?

ExplainThat 1 Junior Poster in Training

You need to be more precise when you post questions of this sort. Brief answer is - hard to tell unless you tell us which DB. Unless it is something really obscure you should have no trouble connecting to it using ADO. There is no dearth of ADO components around that would do the job. As a first step I suggest going to Torry and checking out what is on offer. I think you are bound to find a freebie that will do what you are after - this is not a rocket science sort of problem

ExplainThat 1 Junior Poster in Training

You appear to have got a nice conversation going Lynxus & Duos so I hesitate to butt in. However, having looked at the original post there are a few issues that struck me so I thought I would comment.

  • Running a case statement block each time you want to change a digit and then loading multiple images from file does not sound like a great way to do things.
  • A better approach would be to overlay all digits, 0-9, one on top of the other for each number in your display. Set their visibility to false and on each tick of your timer simply set it to true for the digit to be displayed.
  • A better approach would be not to use images at all - it is pretty easy to create a calculator-style 7 segment display using aligned shapes inside a panel. With that done all you need to do on each timer tick is to show/hide the relevant segments for each digit. I am suggesting this beause I am assuming that you cannot simply use a 7-seg LED component (plenty of those around and I have one of my own somewhere)

If you want to figure out some of the Math involved in programming such a display I have a CSS version of it here

http://www.explainth.at/en/css/csscapt.shtml

ExplainThat 1 Junior Poster in Training

Don't know if you are still looking for a better solution Alastair but here is one anyway. It uses Delphi but given that it relies on the CoCreateGUID function to generate random sequences you should be able to implement something similar in Pascal on Windows as well as in NIX.

As others have pointed out software based random numbers are never truly random - an algorithm of some description is used to produce them.

Algorithm=Logic.

Logic != Random.

If you have trawled the net or read up on random numbers in any good patterns book you will have run into a number of algorithms that help improve things - ususally by using a more complex algorithm etc. However, you don't really need to implement a more complex algorithm yourself. The algorithm used to generate GUIDs is frighteningly complex and, best of all, it is there!

That is what I have used. Download the attachment and enjoy.

ExplainThat 1 Junior Poster in Training

Hello, I'm looking for the about using USB port with a Microchip microcontroller, and I don't know what to do. I already did something similar with the RS232 serial port and worked.

There is an excellent freebie DLL called inpout32.dll which makes it very easy to interface with all kinds of devices. I can't recall using it to access a USB drive but I suspect it does that too.

You can get it here

http://http://logix4u.net/Legacy_Ports/Parallel_Port/Inpout32.dll_for_Windows_98/2000/NT/XP.html

ExplainThat 1 Junior Poster in Training

I'm working on a Delphi program designed for use with an Access database. In addition to the onscreen output, however, my boss wants me to provide PHP reports for it as well. We have PHP installed on our servers, so that's good, but the database in question is installed on the client box in this scenario; it'll be on the same box as my Delphi system is running on. In order to get the PHP page to read it, at the very least I'll need to be able to have the Delphi program pass the IP address of the system it's running on to the PHP page it's calling. How would I go about using Delphi to find this information?

EnderX, I don't think there is any way to do what you want using Delphi on its on. However, rope in WinSock and you have a very simple solution using the various WinSock API functions. The attachment to this message contains all the code you need. I am storing your IP address in a global variable called _LocalIP - better than having to call WinSock functions over and over again each time you need to use your IP. If you like you can change that and turn it into a function that returns your IP as the result.


I cobbled this together using some code I have for other needs and it has not been tested. However, there should be no major bugs. If necessary check out …

ExplainThat 1 Junior Poster in Training

You could also use a with statement. In this particular case it all comes down personal preference, as the compiler will do the same thing either way... If I only have to type it once or twice I personally find it more unwieldy to type in a temp.


As for the exception, that is intentional. If the list is not composed entirely of stringified floats then it cannot be summed. (Two plus green apple makes no sense.) Hence, the exception.

However, I should have said something about the exception. (I just assumed that the OP would notice that --my bad.)

In general, exceptions should not be bound into the code that may generate them, but at an "operational boundary" (as I will call it). That is, permit exceptions to unwind as far back as is reasonable. In the case of an OnClick event procedure, a user-input error should be bound to the outermost block of the procedure itself:

procedure MyForm.SumButtonClick( Sender: TObject );
  var total: double;
  begin
  try
    total := SumListBox1;
    showMessage( 'The total is ' +floatToStr( total ) )
  except
    on EConvertError do begin
      ShowMessage(
        'All the items must be numbers if you want to add them.'
        );
      ListBox1.setFocus
      end
  end
  end;

The only exception I catch here is the only one that is both not fatal and entirely possible due to bad user input. Other exceptions continue to unwind. Since bad input is always possible, the user is informed of his error, the offending listbox is focused, and …

ExplainThat 1 Junior Poster in Training

I've never done it, but I think you just need to tell the tray to repaint itself.
You should be able to do it with something like the following:

var
  shelltraywnd, traynotifywnd, clockwnd: HWND;
begin
  shelltraywnd := FindWindowEx( 0, 0, 'shell_traywnd', nil );
  traynotifywnd := FindWindowEx( shelltraywnd, 0, 'traynotifywnd', nil );
  clockwnd := FindWindowEx( traynotifywnd, 0, 'trayclockwclass', nil );
  SendMessage( clockwnd, WM_PAINT, 0, 0 )
end;

Let us know if that doesn't work.

I am almost certain that works. In case it does not, here is a trick I remember using

  • Change the registry strings
  • Use the Windows GetLocalTime function to fetch the current time in a SystemTime structure.
  • Sleep(1)
  • Call Windows SetLocalTime using the SystemTime data obtained above.

I remember doing this but not with WindowsXP. Seem to recall that I did a Sleep(1) to ensure that Windows recognized that the time was in fact different.

This is nothing short of a cheap hack. Try the tray repaint technique first.

ExplainThat 1 Junior Poster in Training

Thankyou very much "ExplainThat "
whold you please send me a simple Example code for using registry Object?
Thankyou

End of my working day here so a detailed example will have to wait for tomorrow. If you really want to have a go at it right away just take a look at the TRegistry object methods in Delphi help. Your code would go something like this

with TRegistry.Create(Self) do
try
  OpenKey(...);
  //modify key contents here
finally Free end;

Quoting from memory so there might be errors. TRegistry is not hard to play with so you might find that the examples in Delphi Help sufficient. Do post a message saying if you have managed on your own so I don't end up spending time telling what you already know.

ExplainThat 1 Junior Poster in Training

Dear Duas
Thankyou for Your Answer.
about your question I mast Say No I want to changing format of OS time by sume Delphi instructions

One way would be to change the Windows Registry settings directly. The entries you are looking for are the sLongDate, sShortDate and sTimeFormat strings under HKEY_CURRENT_USER\Control Panel\International. You can use the Delphi TRegistry object to manipulate these entries.

ExplainThat 1 Junior Poster in Training

Use a loop:

var
  total: double;
  cntr: integer;
begin
  total := 0.0;
  for cntr := 0 to ListBox1.items.count -1 do
    total := total +strToFloat( ListBox1.items[ cntr ] );
  showMessage( 'The total is ' +floatToStr( total ) )
end;

Might I suggest two changes

  • Rather than doing ListBox1.items inside the loop, just store a reference as AList:=ListBox1.Items and use that.
  • strToFloat will trigger an exception if the ListBox entry is not numeric. There are two solutions - a. Use StrToFloatDef, b. wrap the loop in a try..except block and show an error message
ExplainThat 1 Junior Poster in Training

I'm just curious, I was using setLength to increment my arrays all the while but i've been hoping..

is there any push and pop functions for delphi so that i can dynamically put values into my array without having to code anything myself to increase the array size?

ADrive, pushing and popping in that way goes entirely against the whole philosophy of Pascal. The raw code to do what you want goes something like this

1. type TADriveArr = array[MAXWORD] of Integer;
2.        PADriveArr = ^TADriveArr;

procedure UseADriveArr;
3. var P:PADriveArr;

   procedure ExpConArray(ACount);
   begin
4.       ReAllocMem(P,ACount*sizeof(Integer));
   end;
begin
5.   P:=AllocMem(sizeof(Integer)*32);
try
  //DoSomeStuff
6.  if TestCond then ExpConArra(96)y else ExpConArray(16);
  //DoMoreStuff  e.g. P^[1]:=255;
finally ReAllocMem(P,0) end;
end;

The key features you need to understand here are these

  1. The type declaration is just that - the declaration of an intent to use an array of the specified type having a maximum of MAXWORD elements. Naturally, you can use a different type and a different number of maximum elements. Remember that your first index will be zero!
  2. The pointer is required for us to handle dynamic memory allocation to manipulate an array of type TADriveArr
  3. We use a local variable of type PADriveArr
  4. The ExpConArray function is used to change the size of the array. This is the only way to do the equivalent Push and Pop in Delphi. Remember that if you attempt to dereference an array element you have not assigned memory for, Delphi will oblige! Write to that location …
ExplainThat 1 Junior Poster in Training

thanks explainthat, its really very informative.

but what i really wanted to do was to be able to use one variable to represent different types of database connection, one was TADOConnection, another TOraQuery, both sharing same qry variable.

this is because they both have some similiar method names and thus i could probably reduce my code lines by eliminating the need to do alot of conditional statements and switch between different variable types.

Like I explained, you should be able to do that with a combination of a typecast and a with statement as I have done.

var qry:Pointer;//or TObject if you want it that way
qry:=TADOConnection.Create(nil);
with TADOConnection(qry) do
begin
   //full access to TADOConnection methods and properties here
end;

with TOraQuery(qry) do
begin
   //ditto
end;

Post your actual code - not working if that happens to be the case - if this does not make complete sense and I'll correct it for you.

ExplainThat 1 Junior Poster in Training

ADrive, it may be possible that you have not fully understood just how Delphi typecasts work. First thing first - though not wrong, it does strike me as odd that you should assign the object you want to typecast as a TObject - I would have used a raw pointer. Secondly, what you have done is not really a typecast at all. I provide a few examples below which might point you in the right direction.

  • Imagine that we have a TMaskEdit component on a form
  • You want to use the OnClick event handler for this component
    []]The empty template Delphi gives you will go like this
procedure TMyForm.MaskEdit1Click(Sender:TObject)
begin
   with TMaskEdit(Sender) do
   begin
       MaxLength:=32;
       Text:='Top Secret';
   end;
end;

Here we done the typecast as TMaskEdit(Sender). The with block ensures that the properties MaxLength and Text of your TMaskEdit control can be correctly accessed.

Here is another way to do the same thing

procedure TMyForm.MaskEdit1Click(Sender:TObject)
var AEdit:TMaskEdit absolute Sender;
begin
   with AEdit do
   begin
       MaxLength:=32;
       Text:='Top Secret';
   end;
end;

Here we dispense with the explicit typecast. Instead we declare a local TMaskEdit variable which sits at the same memory location as the Sender parameter. Note that you have not created a new TMaskEdit object - you are simply referencing the Sender object in a different way.

Now look at something closer to your own example

procedure TMyForm.MyADOCode;
var qry:TObject;
//like I said, I would rather do var qry:Pointer;
begin
   qry:=TOraQuery.Create(nil);
   with TOraQuery(qry) do
   begin
       SQL.Add('Delete …
ExplainThat 1 Junior Poster in Training

Hi, maybe can you can help me. I need to write a pascal a program which would read text file from hard disk and would sort all text's words to 3 columns, and would save results to the another file. Let's say that we have no more than 1000 words in the given text file.

Something like that, you have a text:

sdfsdf sdfsdf dfdf sdfsdf, sdfsdf. sdfssdfdf sdfsdf, sdfsdf. sdfsd sdfsndf dfd ....

And I must get a result to 3 colums:

word word word
word word word
word word word
word word word
... .... ....

I would be very thankful if you could help me! ;)

As Squidd says - we need more details. Also, make sure you tell us whether you want to use vanilla Pascal or Delphi - I imagine the former. If you are using Delphi then try not to go down the route of doing this task badly by using visual controls to handle your sorting. b.t.w - what are your sort criteria?

ExplainThat 1 Junior Poster in Training

You are correct that I have came from a pascal background, however the assignment requires me to use what I've learned in pascal and some delphi to do this.

Thanks for your help.

I would say that making good use of Delphi stock classes is perfectly legit and shows great initiative. However, ultimately it is your teacher who will decide.

ExplainThat 1 Junior Poster in Training

Lynxus, I guess you are coming to Delphi from a Pascal background? In general it doesn't make much sense to use the Pascal file functions in Delphi. Streaming data to/from disk is better handled using the TFileStream and TMemoryStream classes. In your case, even that is not necessary - just use the native methods of TStringList instead.

If I understand your assignment correctly you are required to provide means of handling a simple flat file database. Why not simply store the database as a text file? Individual records would be CRLF delimited. Within each record the individual fields would be delimited using a safe character, e.g. |.

The structure would be

FirstNameA|LastNameA|EmployeeIDA|SalaryA
FirstNameB|LastNameB|EmployeeIDB|SalaryB
.......
FirstNamen|LastNamen|EmployeeIDn|Salaryn

Use the Delphi TStringList class to manage this database. Look at Delphi help on TStringList
for starters. Pay particular attention to the following properties and methods

  • Strings[]
  • Count
  • Text
  • CommaText
  • Insert
  • Delete
  • SaveToFile
  • LoadFromFile

Let the SaveToFile & LoadFromFile methods handle all streaming operations. You can use the Strings array to navigate through records in your database. The Insert & Delete methods can be used to add/delete individual employee records.

I suggest using | as a field separator so you can have spaces and commas in your individual field entries. Building records from supplied data is easy. Displaying existing records involves breaking up the record at each | to find its individual fields. Use the Pos function to do this.

As a general observation always try to …

ExplainThat 1 Junior Poster in Training

I have one form that is doing a security check. if the serial number or whatever is found, then a button will appear to open the actual program.

Welp, that isnt working out so well.

How do I have a Tbutton open another form and close the first form? This has been quite frustrating. I have tried everything I know. Under Options I have the first form under auto-create. The other form is under available forms. No matter what i try, I cant get the other form to show up and the first form to disappear.

Any help would be greatly appreciated.

Squidd

There are several ways of accomplishing what you have described. The technique I tested out is best understood by looking at the code in the attachment to the message and trying out the exe that is enclosed.

  1. As you almost certainly know, a Delphi application can be assigned a main form
  2. When the mainform is destroyed the application terminates.
  3. An interesting property is TApplication.ShowMainForm. By default this is true - you can set it to false as I have done. Look at the .DPR code using the Project Menu, Show Source menu item.
  4. Actually, this is not necessary - you can simply make the MainForm invisible by setting its Visible property to False.
  5. All Delphi objects have a virtual method called AfterConstruction that does nothing. However you can override it to do special processing. This is what I have done in TMaster.AfterConstruction. I call the …
ExplainThat 1 Junior Poster in Training

Code is as follows:

1: This is what I posted for the alphabetical and somenumerical values in the list that is loaded.

procedure TMainForm.SortListButtonClick(Sender: TObject);
begin
  ListView1.SortType := stBoth;
  CurrentStatusLabel.caption := 'List Sorted';
end;

I would like to also sort it from z - a... that is the problem atm...

2: Sort a list numerically... tried stdata..

ListView1.SortType := stData;

this does not truly sort numerically...

3: Capitalize the first letter in a list or all first letters in a list... no idea. Not much luck on reading up on it. Most code I saw was applied to other edit boxes and not tlistview.

4: Reversing the order of a line in listview.. Cant get that to work either and looking it up hasn't afforded much help either. I was given this to start off with.

s[ 1 ] := UpCase( s[ 1 ] );

so there you have it. :( im new

Thanks for any help...

Squidd, whenever you look up Delphi help - e.g. for SortType - also make sure that you check out the entries under See Also.

In this instance what you need is to checkout the OnCompare. event. You can use this event to alter the way the sort is being done. Here is some, untested, code that should do your reverse sort

procedure TMaster.WhenLVCompare(Sender:TObject;Item1,Item2:TListItem;Data:Integer;var Compare:Integer);
begin
    Compare:=CompareText(Item2.Caption,Item1.Caption);
end;

As to the problem with capitalization - remember that you will need to update the corrected entry in the listview. Thus if you have the code

procedure TMaster.InCapLV;
var i:Integer;
     s:String;
ExplainThat 1 Junior Poster in Training

Could be - like I said, I was not sure I had understood the question.

ExplainThat 1 Junior Poster in Training

Squidd it ocurs to me that even if you want to pursue your current solution there is at least one thing you can do to improve it even further -

I note that you are incrementing num_removed each time you remove an item from your listview. This is totally unnecessary. It would be far better to note the number of items in the listview before you start the clean up and then check it again after the cleanup. Something like this

var befLoop:Integer;
befLoop:=lvOne.Items.Count;
//Your cleanup code goes here.
ShowMessage(Format('%d items removed',[befLoop - lvOne.Items.Count]);

b.t.w. given that you are new to this game might I suggest that you get into the habit of naming your controls in a consistent and meaningful way? ListView1 is not a very descriptive name is it? The control serves a purpose in your app so give it a name that reflects that purpose. Also, adopt a naming convention. I suggest a Hugarian notation

buttons - btn...
listviews - lv...

etc.

When you are working on complex forms, such a convention will help you be more productive and efficient.

ExplainThat 1 Junior Poster in Training

I hope I am understanding your question correctly. It seems to me that what you want to do is to evaluate an expression? If that is the case

  • The expression as it stands is merely a string.
  • You need to parse that expression - unlike VB and Javascript Delphi does not have a built in eval function. It is worth typing in eval Delphi in Google to see if it comes up with anything useful.
  • The technique for doing this is called Recursive Descent Parsing. I guess there is Pascal code for this somewhere out there.
  • My personal preference would be to convert the expression to Reverse Polish Notation and then evaluate that. This is a great deal more elegant - and faster. I have an RPN evaluator written up some where - if I can dig it up I'll post a copy here.

Hope this helps.

ExplainThat 1 Junior Poster in Training

The answers to your two questions

  • The right place to get the button to disable would be the TListView.OnInsert event. All you need is something like this: btnCleanUp.Enabled:=(lvOne.Items.Count < 999)
  • I think what you want is to change the icon that appears for your application in Windows Explorer? You can do this from the Application tab in the dialog box that pops up when you click on Project.Options.

Before you spend too much time trying to write more code, might I suggest that you do some or all of the following?

  • Familiarize yourself with Delphi stock objects such as TList, TStringList, TFileStream, TMemoryStream etc. You are likely to spend too much time reinventing the wheel if you don't use these objects. They are all in the Classes unit.
  • Make sure you understand how the with keyword works. Also play around with using try..finally..end and try..except..end blocks. As a general rule try..finallys should outnumber try..excepts by a proportion of 10:1 or more.
  • When you use any object - visual or otherwise - make sure you explore the methods, properties and events for that object.
  • Finally, like I suggested earlier, get the Danny Thorpe book. It is the best Delphi programming investment you could ever make.

Good luck!

ExplainThat 1 Junior Poster in Training

Hello Sqidd,

May I suggest that you get hold of Danny Thorpe's book on Delphi programming? The last time I checked it was out of print but available second hand on Amazon at over $100. A lot of money but money very well spent.

There are a number of things wrong with your code.

  • For starters you actually use a GOTO statement. In over a decade as a Delphi programmer I have never used a GOTO. Quite apart from structural issues, GOTOs generate very poor quality assembler code. NEVER use them.
  • Secondly, what you are doing is little short of a selection sort. With 15000 items it will be relatively slow.
  • You wouldn't normally notice the lack of speed. The problem is that with what you are doing you are deleting listview items one at a time. Each such deletion triggers multiple messages that culminate with a control redraw. Messages are slow. Redraws are slooow and get sloooooooower as the number of items in your listview increase.

As a general obserrvation when you find that you have issues with speed it is better to take a step back and examine your assumptions rather than spend time trying to make it all go faster. In the present instance the two questions that spring to mind right away are

  1. Why not prevent the listview from being populated with duplicates to begin with by checking before adding new items?
  2. What on earth is the point of a …
squidd commented: above my level in programming but noneless a great effort and explanation with code to review as well. Nice job i must say +1
ExplainThat 1 Junior Poster in Training

ADrive, I leave it to you to decide whether you are competent enough to handle RTF programming. I should emphasize that what I suggested does not amount to writing an RTF parser.

Duoas, I humbly beg to differ - manipulating a simplified RTF template inside Delphi, putting in custom content and then letting RTF readers, such as Word, open the document is not difficult. RTF is a remarkably well thought out and organized standard. The RTF generated by many writers - particularly Word - is so full of redundancy that it does appear to be complex. RTF programming does require organization - but that should not come to any shock to any half decent Delphi programmer. To a VB programmer, maybe ;-/

ExplainThat 1 Junior Poster in Training

explainthat, do you mean to tell me RTF actually supports multi level bulletting? because the one from 'word' that came with windows doesn't.

If it does, then yes i'm willing to take a look at it.

It has been a few months since I had anything to do with outputing RTF so I took a quick look at RTF lists. I think there shouldn't be any problem with outputting multilevel lists. Take a look at the RTF documentation - available on MSDN. The information you want is Pages 21-23.

Briefly, an RTF document is made up of a header section, a document information section and then the actual document. The header section contains lists of fonts, colors, styles etc which are then referenced in the docuement itself.

RTF is a vast standard. Most word processors offer pretty good support for reading RTF but what they can write is only a subset of this standard. This applies to Word too. What this means in practice is that just because you cannod do something in Word, either directly or via automation, does not mean that it is not supported.

Just one word of caution - in my experience the number of people using Word 97 is still very significant. There have been some significant changes in the way later versions of the RTF standard so make sure you use the RTF 1.7 spec to ensure maximum compatibility.

There are almost certainly "components" out there that will help you …

ExplainThat 1 Junior Poster in Training

After having struggled to ensure that automating Word from Delphi always works - any OS, any version of Word... I finally ended up creating RTF files instead. This always works, there are no black boxes and you have complete control over the look and feel of every aspect of the document. RTF looks rather scary when you look at it but this is largely because of all the unnecessary garbage that Word puts into an RTF document. In reality it is a really well thought out standard. If want to try an RTF solution PM me and I should be able to help.

If you want to continue with Word...good luck. You will get it working but it will not be long before you want something new and have to begin all over again.

ExplainThat 1 Junior Poster in Training

Guess you are not looking for an alternate solution any more but in case you are - the best thing to do is to create a console app. You should only need to code one unit and from there do the email sending in the initialization section, do any residual housekeeping in the finalization section and you are done.

ExplainThat 1 Junior Poster in Training

Hello.
I would like to show a multiline caption on a button, but with the second line in bold. Can somebody do it?
Currently I have a multiline caption, but don't know how to draw text in different font styles (color, style, size, etc.) within one button.
(Delphi 2006)

Thanks in advance, have a nice day.

If you feel upto the task of editing a .DFM directly, here is how you can do it:

  1. First create your button and size it so it can take two lines of text
  2. You are not going to use the intrinsic button caption so you can simply set it to a null string.
  3. Now create two label controls, anywhere in your form, place them one below the other and assign their Caption Font Alignment and Layout properties so the captions appear pretty much the way you would want them to appear on your button.
  4. Remember to set the AutoSize property to False or else the labels will resize to occupy just as much space as they need when the form is redrawn.
  5. Do Alt + F12 to see the .DFM
  6. Locate the code for your two label controls, cut it and paste it inside the code for the button control.
  7. Do Alt + F12 to see the form in the Delphi IDE
  8. Adjust the Top Left Height and Width properties so the button boundaries are not obscured. This is necessary to ensure that users continue to see a "normal" button …