Paul van der Ven
Iedere zichzelf respecterende NLDelphi bezoeker heeft natuurlijk het artikel van Jos Visser gelezen over het maken van een TDataset afgeleide, de TbigInifileDataset. In dat artikel laat Jos zien hoe een ini-bestand te gebruiken is met behulp van een TDataset-afgeleide.
...Marcel van Beuzekom
Een query gebruik je per definitie om gegevens op te halen. Maar na het ophalen wil
de gebruiker de data ook manipuleren. De gebruiker wil de data in een lijst zien die hij
snel kan sorteren op verschillende kolommen, en uiteraard wil hij de data ook wijzigen.
Een query component is hiervoor al snel te beperkt. Een query is readonly en om de
data te sorteren moet de query opnieuw worden uitgevoerd, met een trage performance als
gevolg.
De BDE en later ook Interbase Express gaven ons al mogelijkheden om met een query
ook data te wijzigen, maar deze oplossingen zijn geen van allen perfect. Een BDE live
query is alleen te gebruiken zolang er geen join wordt gebruikt en is bovendien vrij
traag, BDE cached updates maken tijdelijke Paradox bestanden aan waarin de data wordt
opgeslagen (in het ergste geval op het netwerk!) en Interbase Express Cached updates biedt
weer geen algemene oplossing voor alle databases. De ClientDataSet biedt de mogelijkheid
om data op te halen, sorteren, wijzigen en weer terug op de server op te slaan.
ClientDataSet
ClientDataSet is een component, gemaakt voor het bekijken en wijzigen van data in het
geheugen. Omdat ClientDataSet erft van TDataSet, heeft het component alle
mogelijkheden die een gewone dataset ook heeft: bladeren in data, zoeken, data wijzigen en
alle data-aware componenten gebruiken. Maar ClientDataSet heeft ook verschillende
mogelijkheden om data te sorteren en te groeperen. Omdat zowel het zoeken als het sorteren
allemaal in het geheugen gebeurt is het razendsnel. Pas als de wijzigingen weer moeten
worden opgeslagen hebben we een server of schijf nodig.
Dat opslaan kan de ClientDataSet zelf, maar in zeer beperkte mate. Het opslaan is
alleen mogelijk in één bestand en dat bestand wordt ook altijd helemaal opgeslagen .
Zelfs als je maar één regel hebt gewijzigd wordt dus het hele bestand opgeslagen. Ook
het inlezen gebeurt weer met het hele bestand. Los van de performance is dit ook niet
gewenst in een multi-user omgeving, er kan immers maar één gebruiker tegelijk met het
bestand werken. Toch is ClientDataSet juist voor een multi-user omgeving gemaakt. Voor het
inlezen en opslaan van de data heeft hij alleen een tweede component nodig: een
DataSetProvider.
DataSetprovider
Een DataSetProvider is eigenlijk niets meer dan een doorgeefluik tussen een
ClientDataSet en een 'echte' dataset, bijvoorbeeld een Query. De DataSetProvider laat de
data ophalen door de Query, vat deze data samen in een pakketje en stuurt dat pakketje
naar de ClientDataSet.
Inlezen data van een database naar een ClientDataSet
Stijn van Grinsven ( ook bekend als SVG_1986 )
Stijnsadres@hotmail.com
Altijd al afgevraagd hoe je nou bepaalde informatie over een liedje te weten
kunt komen zonder dat je bij WinAmp moet gaan kijken. In dit artikel kom je te
weten hoe je op zoek moet gaan naar deze informatie in een mp3-bestand.
Natuurlijk zijn er op het internet wel meer van dit soort artikelen te vinden,
maar er zijn er maar weinig die in het Nederlands zijn.
Hoe ziet de Mp3-header eruit?
Kleine uitleg over het mp3-header:
goed, we beginnen meteen met 2 problemen:
Bij de meeste Mp3-bestanden zit er nog een ID3 header voor
We moeten ervoor zorgen dat de ID3-header niet wordt gelezen alsof het de mp3-header is. Wat dit zou natuurlijk fout zijn.
De mp3-header is in plaats van bytes opgebouwd uit bits.
Hierdoor moet er telkens bepaalde bits worden uitgelezen. maar hoe je dat gaat doen mag je zelf bepalen.
De echte header van een mp3-bestand begint met 11x een gesette bit, dus 11x een '1'. Hierdoor is het mogelijk om de echte mp3-header op te zoeken door te zoeken naar 11 gesette bits, hierdoor is het ID3-tag probleem opgelost.
Je zoekt dus een mp3-bestand door naar een byte die een waarde heeft van 255. dan lees je de volgende byte uit en kijk je of de 1e 3 bits zijn geset.
Simpele uitleg over ID3:
Het ID3 is een erg handige uitvinding omdat hierin de gegevens over een liedje kan worden gezet. Zoals de Artiest, de titel van het liedje, het Genre en nog meer. Van de ID3 zijn 2 versies. De 1e versie is de makkelijkste, want deze bestaat in totaal uit 128 bytes en staat op het einde van het bestand. Maar, versie 2 bestaat uit een onbekend aantal bytes en staat bovenaan het bestand. hierdoor ontstaat dus het 1e probleem, omdat je niet weet hoeveel bytes er moeten worden overgeslagen voordat de mp3-header begint.
Bits & Bytes:
De bits en bytes zijn een beetje moeilijk, want deze hebben een rare volgorde ( om het zo maar even te noemen ), zie het voorbeeld:
7 6 5 4 3 2 1 0___ 15 14 13 12 11 10_ 9_ 8
x x x x x x x x____ x__ x__ x__ x__ x__ x__ x_ x
zoals je ziet begin je telkens te tellen van rechts, maar elke byte komt weer van links.
Terug naar het Mp3-bestand:
Nu de Mp3-header nog,
Een mp3-header ziet er zo uit:
Tmp3header = Record
___ Mpeg_version_________ : Tmp3Version;
___ Emphasis________________ : Tmp3Emphasis;
___ Protection_______________ : Boolean;
___ Copyright_______________ : Boolean;
__ Padding__________________ : Boolean;
___ Bitrate_Index__________ : Word;
___ Mode_ext_______________ : Byte;
___ Channel_mode________ :
TMP3Channel_mode;
___ Layer______________________ :
TMP3Layer;
___ Sampling_rate_________ : Word;
___ Original___________________ : Boolean;
End;
Let op dat je een Word gebruikt bij de Bitrate en de Sampling rate, dit worden namelijk waardes hoger dan 256.
bij deze declaratie van de TMp3Header zijn nog wat andere declaraties nodig, anders is deze incompleet:
TMP3Channel_mode = (MCMStereo,
MCMJoint_stereo, MCMDual_channel, MCMSingle_channel);
TMP3Version = (MV_ERROR, MV_MPEG_1, MV_MPEG_2, MV_MPEG_2_5);
TMP3Layer = (ML_ERROR, ML_I, ML_II, ML_III);
TMP3Empasis = ( ME_NONE, ME_50_15ms,
ME_RESERVED, ME_CCIT_J17);
Hier zijn de conversies naar een String, zodat hierover niet
moeilijk hoeft worden gedaan:
Version_String: array [0..3] of
String ________ =
_ _____________________ ('Error', 'MPEG I',
'MPEG II', 'MPEG III');
Layer_String: Array [0..3] of
String
=__
('Error', 'Layer I', 'Layer II', 'Layer
III');
Channel_String: Array [0..3] of
String _______ =
('Stereo', 'Joint Stereo', 'Dual Channel', 'Single
channel');
Emphasis_String: Array [0..3] of
String _____ =
('None', '50/15 ms', 'Reserved', 'CCIT J.17');
Ik ga nu verder met hoe de header eruitziet en hoe met de info van de header moet worden opgegaan. De header bestaat uit 4 bytes ( 32 bits ). Ik ga nu verder met de 32 bits, omdat het dan misschien duidelijk is, let wel op dat de 11 gesette bits meegerekend zijn in deze 32 bits.
Hier een plaatje hoe de header eruit ziet:
Hier zie je heel
snel hoeveel bits elk deel van de header nodig heeft. Toch staat hier nog een
keer het aantal bits dat je nodig hebt in een tabel:
_Voor Copyright:
Het lied is copyrighted of het is het niet
Voor Original:
Het lied is het originele of het is een copy van het originele liedje.
Ik heb deze informatie gehaald van:
http://home.swipnet.se/grd/mp3info/frmheader/index.html
de unit die hiermee is gemaakt is getest over verschillende
mp3-bestanden. Bij elk van deze bestanden waren de gegevens goed. De inhoud van
dit artikel zijn dus te vertrouwen.
ik heb de bovenstaande pagina vertaald en heb er een betere uitleg bijgegeven hoe het moet worden uitgelezen. Ik hoop dat in ieder geval 1 iemand er blij mee is. En ik hoor het graag als er fouten zijn, of als je mij gewoon wilt bedankt.
Ook kun je mij vragen naar de complete code op dit mailadres. Maar het is eigenlijk de bedoeling dat je zelf een mp3-header lezer gaat maken.
Stijn van Grinsven
lid van
www.NLDelphi.com
Marcel van Beuzekom
Eén van de nieuwe technieken die we tegenkomen in Delphi 6
is 'Web Services'. Dit artikel legt je uit wat Web Services zijn, hoe je een
server kunt maken en wat een client moet doen om met zo'n Web Service te
communiceren.
Wat zijn Web Services?
Web Services zijn objecten die gebruikt kunnen worden via een netwerk,
bijvoorbeeld internet. Web Services zijn platform onafhankelijk en
programmeeromgeving onafhankelijk. Een object geschreven in de ene taal kan dus
worden gebruikt in de andere taal. Het platform waar de server en client op
draaien is niet van belang.
Het kan zijn dat deze beschrijving je erg bekend voorkomt, het zou namelijk
ook een beschrijving van COM/DCOM kunnen zijn. Wat is er dan nieuw? Eigenlijk
niets! DCOM is alleen nooit helemaal geworden wat het zou moeten zijn, namelijk
een platform onafhankelijk systeem. Een ander nadeel van DCOM is dat het een
protocol is naast de standaard protocollen zoals http, pop news enzovoort.
Verder vereist DCOM nogal wat administratie en registratie in het netwerk, op
zich niet vreemd omdat bij DCOM de beveiliging door het besturingssysteem
gebeurd. Kortom, DCOM is zeer goed in wat het moet doen, maar multi platform is
het nooit geworden. Web Services belooft dat wel te bereiken.
Waarom zou Web Services nou wel het succes kunnen worden waar dat bij DCOM
niet helemaal lukte? De technieken die Web Services gebruiken zijn: SOAP,
HTTP, GET/POST, MIME en XML. Kortom, het is een verzameling van bestaande
technieken in plaats van een compleet nieuwe techniek. Er hoeft dus weinig te
worden geconfigureerd op de server (publiceren is voldoende) en op de client.
Ook firewalls hoeven niet speciaal te worden aangepast omdat Web Services over
standaard HTTP draaien.
Een andere mogelijke succesfactor is het feit dat het World Wide Web
Consortium heeft vastgelegd waaraan een webservice moet voldoen. Het verleden
heeft bewezen dat dat nog geen garantie is dat iedereen zich aan die standaard
houdt, denk maar aan de HTML uitbreidingen die zowel Microsoft als Netscape
verzonnen zonder dit in een standaard vast te leggen. Maar de standaard is er en
die is door een onafhankelijke partij vastgelegd.
Overigens worden SOAP en
Web Services vaak door elkaar gebruikt, dat is niet helemaal terecht. SOAP is
één van de protocollen die gebruikt kan worden voor Web Services, maar dat zou
net zo makkelijk een ander protocol kunnen zijn. Borland houdt het voorlopig bij
SOAP, wij sluiten ons daar maar bij aan.
WSDL
De standaard van W3C beschrijft onder andere dat er een Web Services
Description Language (WSDL) moet zijn. Een WSDL is een XML-document waarin
wordt beschreven wat de mogelijkheden van een Web Service zijn, het 'contract' naar
de buitenwereld. Ook hier zie je weer een overeenkomst met COM: de WSDL van een
Web Service is vergelijkbaar met de interface van een COM object.
Zonder op alle details in te gaan: er zijn dus een aantal afspraken waaraan we ons moeten houden voordat we
een Web Service kunnen gaan bouwen. Maar gelukkig zijn wij
...
Marcel van Beuzekom
Na de eerste blik op Delphi 6 wordt het nu tijd om de
component palette eens wat beter te gaan bekijken. Welke nieuwe componenten
hebben we er bij gekregen en waar zijn uitbreidingen in gemaakt?
TValueListEditor
De ValueListEditor is een grid waarin de gebruiker op een eenvoudige manier
variabelen en hun waarden kan wijzigen of toevoegen. Vaak wordt data in een Na
manier in stringlists opgeslagen, nu kan deze data ook worden gepresenteerd en
gewijzigd. De kolommen heten standaard Key en Value, maar de
titels kunnen ook worden aangepast of verwijderd. Ook kan worden ingesteld of de
gebruiker alleen de waarde mag wijzigen, of ook de naam kolom. Via de
(public) property ItemProps kan vervolgens worden ingesteld h??e de gebruiker de
waarde mag wijzigen, bijvoorbeeld met een editmask, maar ook een lijstje met
keuzemogelijkheden is mogelijk.
TLabeledEdit
De naam LabeledEdit zegt het eigenlijk al: een label en een edit in één.
Van de label kan worden opgegeven waar deze, relatief aan de edit, moet komen
staan. Verder maakt dit component dankbaar gebruik van de mogelijkheid om
properties van een gekoppeld component te kunnen wijzigen: de properties van het
label component hoeven niet opnieuw te worden gepublished, alleen het publishen
van het component voldoet, de object inspector doet de rest.
TColorBox
Een populair component in de third party libraries, al was het alleen maar
omdat het er zo leuk uitziet: een combobox om een kleur te selecteren. Nu dus
ook standaard in Delphi.
TActionManager
Sinds Delphi 5 zijn Actions niet meer weg te denken uit een gestructureerde manier
van programmeren.
...
Marcel van Beuzekom
In de persberichten
die Borland naar buiten bracht
v????r het uitbrengen van Delphi 6 werd het al duidelijk: we moeten weer een
hele verzameling nieuwe termen leren. Sommige termen bestonden al, maar waren
nieuw in combinatie met Delphi (Soap, XML, WSDL, XSL), andere termen waren helemaal
nieuw (BizSnap, WebSnap, DataSnap, dbExpress). Maar, wat is er
nou eigenlijk nieuw in Delphi 6? Volg de serie artikelen op NLDelphi en je bent
helemaal klaar voor de overgang.
De installatie
Bij de
installatie wordt de stijl meteen duidelijk, Borland heeft deze keer gekozen
voor blauw en strak.
We
kunnen uiteraard kiezen voor Delphi 6, maar ook de andere programma's die we
van Delphi 5 al kennen zijn er allemaal nog. De installatie heeft ook weer een
optie om alleen de registry instellingen te installeren en bij de installatie
wordt gevraagd of de bestandtypes gekoppeld moeten worden aan Delphi 6. Handig
als je 6 alleen installeert om te testen en 5 nog nodig hebt voor je dagelijkse
werkzaamheden.
Na de installatie wordt je, bij het opstarten van Delphi, meteen
de mogelijkheid geboden om jezelf te registreren. Uiteraard kun je deze
registratie ook later uitvoeren. Meer informatie hierover vind je bij de
links onderaan dit artikel.
De IDE
Na het opstarten
valleen meteen een aantal dingen op, onder andere de tabs onderaan de code
editor: Code en Diagram. Klik je op diagram dan krijg je een Diagram Editor
zoals je die al van de Delphi 5 datamodules kent maar
...
Ik heb ooit iets geprobeerd in die richting (meer dan 10 jaar gelden :-)
Gr. Peter
Hoi
Ik probeer het volgende te realiseren maar weet niet of het mogelijk is.
IK heb een panel en daarin zitten een aantal andere
Thx, die losse pols van jou doet het prima, werkt prima.
Herby 24-May-23, 18:20Ik denk op een soortgelijke manier als dit (even uit de losse pols):
function FindFirstControl(AParent: TWinControl; AClass: TClass): TControl;
Hoe zou jij het dan opgelost hebben?
Herby 24-May-23, 16:48
TPanel Drag & Drop mogelijkheid
Hoi Peter,
Herby 28-May-23, 17:09Ik had al een soortgelijk voorbeeld gevonden maar loop tegen de nodige issues aan.
Grootste probleem waar ik tegenaan loop