IdFTPServer Exception 'Connection reset by peer' - c++builder

I've setup a simple FTPServer that only serves a specific purpose. Watching the code when a get is performed, I see GetFileDate and GetFileSize called twice, but I never see RetrieveFile being called. Instead, the client shows an exception of 'Connection reset by peer'.
All of the properties of IdFTPServer are default except for AllowAnonymousLogin. 100% of the FTP Server code is being shown:
I've tried changing the TerminateWaitTimeout value, but that didn't help.
__fastcall TFTPServer::TFTPServer(TComponent* Owner) : TDataModule(Owner)
{
root = IncludeTrailingPathDelimiter(GetCurrentDir()) + "files\\";
IdFTPServer1->Active = true;
}
// ---------------------------------------------------------------------------
void __fastcall TFTPServer::Close(void)
{
IdFTPServer1->Active = false;
}
// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1FileExistCheck(TIdFTPServerContext *ASender, const UnicodeString APathName, bool &VExist)
{
String file = StringReplace(APathName, "/", "", TReplaceFlags() << rfReplaceAll);
TSearchRec sr;
int done = FindFirst(root + file, 0, sr);
VExist = (done == 0);
FindClose(sr);
}
// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1GetFileDate(TIdFTPServerContext *ASender, const UnicodeString AFilename, TDateTime &VFileDate)
{
String file = StringReplace(AFilename, "/", "", TReplaceFlags() << rfReplaceAll);
TSearchRec sr;
int done = FindFirst(root + file, 0, sr);
if (done == 0)
{
VFileDate = sr.TimeStamp;
}
FindClose(sr);
}
// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1GetFileSize(TIdFTPServerContext *ASender, const UnicodeString AFilename, __int64 &VFileSize)
{
String file = StringReplace(AFilename, "/", "", TReplaceFlags() << rfReplaceAll);
TSearchRec sr;
int done = FindFirst(root + file, 0, sr);
if (done == 0)
{
VFileSize = sr.Size;
}
FindClose(sr);
}
// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1RetrieveFile(TIdFTPServerContext *ASender, const UnicodeString AFileName, TStream *&VStream)
{
String file = StringReplace(AFileName, "/", "", TReplaceFlags() << rfReplaceAll);
VStream = new TFileStream(root + file, fmOpenRead);
}
// ---------------------------------------------------------------------------
What am I missing?

Related

Directory listing in c++ Builder 6

I need to get a directory listing of a specific directory (like dir /b in cmd) that is in the same place as my app's exe file.
Here is what I have tried:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
BROWSEINFO BrowsingInfo;
LPITEMIDLIST ItemID;
char szDirPath[MAX_PATH];
memset(&BrowsingInfo, 0, sizeof(BROWSEINFO));
memset(szDirPath, 0, MAX_PATH);
memset(szFolderName, 0, MAX_PATH);
BrowsingInfo.hwndOwner = Application->Handle;
BrowsingInfo.lpszTitle = "Select A Folder";
BrowsingInfo.ulFlags = BIF_RETURNONLYFSDIRS;
ItemID = SHBrowseForFolder(&BrowsingInfo);
SHGetPathFromIDList(ItemID, szDirPath);
Label1->Caption = szDirPath;
}
That code gives you a path to a folder that is selected by the user.
To then get the contents of that folder, you have to enumerate the contents manually. You have a few options for that:
Microsoft's Win32 API FindFirstFile() and FindNextFile() functions:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
BROWSEINFO BrowsingInfo = {};
BrowsingInfo.hwndOwner = this->Handle;
BrowsingInfo.lpszTitle = "Select A Folder";
BrowsingInfo.ulFlags = BIF_RETURNONLYFSDIRS;
LPITEMIDLIST ItemID = SHBrowseForFolder(&BrowsingInfo);
if (!ItemID)
return;
char szDirPath[MAX_PATH] = {};
bool bDirPathOK = SHGetPathFromIDListA(ItemID, szDirPath);
CoTaskMemFree(ItemID);
if (!bDirPathOK)
return;
Label1->Caption = szDirPath;
WIN32_FIND_DATAA fd;
HANDLE hFind = FindFirstFileA((Label1->Caption+"\\*").c_str(), &fd);
if (hFind == INVALID_HANDLE_VALUE)
return;
do {
if ((strcmp(fd.cFileName, ".") != 0) && (strcmp(fd.cFileName, "..") != 0)) {
// use fd as needed...
}
}
while (FindNextFileA(hFind, &fd));
FindClose(hFind);
}
C++Builder's FindFirst() and FindNext() functions (in SysUtils.hpp):
#include <SysUtils.hpp>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
BROWSEINFO BrowsingInfo = {};
BrowsingInfo.hwndOwner = this->Handle;
BrowsingInfo.lpszTitle = "Select A Folder";
BrowsingInfo.ulFlags = BIF_RETURNONLYFSDIRS;
LPITEMIDLIST ItemID = SHBrowseForFolder(&BrowsingInfo);
if (!ItemID)
return;
char szDirPath[MAX_PATH];
bool bDirPathOK = SHGetPathFromIDListA(ItemID, szDirPath);
CoTaskMemFree(ItemID);
if (!bDirPathOK)
return;
Label1->Caption = szDirPath;
TSearchRec sr;
if (FindFirst(Label1->Caption+"\\*", faAnyFile, sr) != 0)
return;
do {
if ((sr.Name != ".") && (sr.Name != "..")) {
// use sr as needed...
}
}
while (FindNext(sr) == 0);
FindClose(sr);
}
Microsoft's Win32 API IShellFolder interface, in particular its EnumObjects() method:
#include <shlobj.h>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
BROWSEINFO BrowsingInfo = {};
BrowsingInfo.hwndOwner = this->Handle;
BrowsingInfo.lpszTitle = "Select A Folder";
BrowsingInfo.ulFlags = BIF_RETURNONLYFSDIRS;
LPITEMIDLIST ItemID = SHBrowseForFolder(&BrowsingInfo);
if (!ItemID)
return;
char szDirPath[MAX_PATH];
if (!SHGetPathFromIDListA(ItemID, szDirPath)) {
CoTaskMemFree(ItemID);
return;
}
Label1->Caption = szDirPath;
IShellFolder *desktop;
if (FAILED(SHGetDesktopFolder(&desktop))) {
CoTaskMemFree(ItemID);
return;
}
IShellFolder *sf;
HRESULT hres = desktop->BindToObject(ItemID, NULL, IID_IShellFolder, (void**)&sf);
desktop->Release();
CoTaskMemFree(ItemID);
if (FAILED(hres))
return;
IEnumIDList *enum;
if (FAILED(sf->EnumObjects(this->Handle, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &enum))) {
sf->Release();
return;
}
PITEMID_CHILD ChildID;
while (enum->Next(1, &ChildID, NULL) == S_OK) {
// use ChildID as needed, such as with
// sf->GetAttributesOf(), sf->GetDisplayNameOf(), etc...
CoTaskMemFree(ChildID);
}
enum->Release();
sf->Release();
}
BTW, C++Builder also has a SelectDirectory() function (in FileCtrl.hpp) that wraps the SHBrowseForFolder() API for you:
#include <FileCtrl.hpp>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String DirPath;
if (!SelectDirectory("Select A Folder", L"", DirPath))
return;
Label1->Caption = DirPath;
...
}

TIdTCPServer not working after upgrading to C++Builder 11

The following code worked in C++Builder 10.3 Rio to stream a file across the network. After upgrading to C++Builder 11 Alexandria, fileStreamerExecute() never gets called. The file does get created at path, but is zero length and is in use, so any attempt to open the file fails. I'm guessing some changes occurred with Indy and so some changes are required in my code?
//---------------------------------------------------------------------------
void Tdata::stream_file(String path, Tstream_dir direction)
{
_stream_path = path;
_stream_dir = direction;
if (_fs)
delete _fs;
if (_stream_dir == sdIn)
_fs = new TFileStream(_stream_path, fmCreate | fmShareDenyNone);
else
_fs = new TFileStream(_stream_path, fmOpenRead | fmShareDenyNone);
fileStreamer->DefaultPort = 9965;
fileStreamer->Active = true;
}
//---------------------------------------------------------------------------
void __fastcall Tdata::fileStreamerExecute(TIdContext *AContext)
{
if (_stream_dir == sdIn)
{
try
{
_fs->Position = 0;
AContext->Connection->IOHandler->ReadStream(_fs, -1, true);
}
__finally
{
delete _fs;
_fs = 0;
}
AContext->Connection->Disconnect();
}
else
{
try
{
AContext->Connection->IOHandler->Write(_fs);
}
__finally
{
delete _fs;
_fs = 0;
}
AContext->Connection->Disconnect();
}
}
// ---------------------------------------------------------------------------
__fastcall TstartForm::TstartForm(TComponent* Owner) : TForm(Owner)
{
char hostname[256];
String host_ip = "";
_progressForm = 0;
if (gethostname(hostname, 256) == 0) {
hostent *host = gethostbyname(hostname);
if (host) {
char *addr = host->h_addr;
if (addr) {
host_ip = String(inet_ntoa(*(in_addr*) addr));
// returns "192.168.180.1" from VMWare network adaptor
// hard code to correct value for testing
host_ip = "192.168.1.226";
}
}
}
}
EDIT: updated to get the local IP like this instead, and now things are working:
__fastcall TstartForm::TstartForm(TComponent* Owner) : TForm(Owner)
{
_progressForm = 0;
String host_ip = L"";
TIdStackWindows* id_stack = new TIdStackWindows;
if (id_stack) {
host_ip = id_stack->LocalAddress;
delete id_stack;
}
}
EDIT: updated to get the local IP per Remy's Recommendation
__fastcall TstartForm::TstartForm(TComponent* Owner) : TForm(Owner)
{
_progressForm = 0;
String host_ip = L"";
TIdStack::IncUsage();
host_ip = GStack->LocalAddress;
TIdStack::DecUsage();
sm->_this_computer_id = host_ip;
}

How did TIdTCPServer multicast to ALL Clients in A 60Hz timer?

I am a newbie working with Indy. This is my first time posting a question here.
My project has to send data to all clients at 60Hz. I am using TIdTCPServer for this, and to monitor keep-alives. My tool is very old, running on WinXP, using C++Builder 6 and Indy 8. There is a potential timeout issue, does anyone have a good thought how to handle it?
Here is my code:
Server Side
typedef struct
{
AnsiString PeerIP; //{ Cleint IP address }
AnsiString HostName; //{ Hostname }
int Id; // {Cleint ID}
} TClient;
// This is Multimedia timer callback function, on 60Hz
void CALLBACK mmTimerProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
DWORD T1, T2;
TfmMain *pMain = (TfmMain *)dwUser;
int Index;
double dT;
TClient *pClient;
if (pMain->IsClosing) return;
if (pMain->Shutdown)
{
return;
}
pMain->UpdateServer1Data();
TList *pList = pMain->IdTCPServer1->Threads->LockList();
try
{
for(int X = 0; X < pList->Count; X++)
{
if (!pMain->IsClosing)
{
TIdPeerThread *AThread = (TIdPeerThread *)pList->Items[X];
if(AThread != NULL)
{
pClient = (TClient *)AThread->Data;
try
{
if(!AThread->Connection->ClosedGracefully)
{
// Send data to ALL Clients
AThread->Connection->WriteBuffer(&pMain->Data2Client, sizeof(pMain->Data2Client), true);
}
}
catch(Exception &E)
{
if(!AThread->Stopped)
{
AThread->Stop();
AThread->Connection->Disconnect();
}
}
}
}
}
}
__finally
{
pMain->IdTCPServer1->Threads->UnlockList();
}
// Shutdown computer or close application
if(pMain->SimIos.Status.iSimStatus == 11)
{
pMain->Shutdown = true;
pMain->CloseApp();
}
}
void __fastcall TfmMain::IdTCPServer1Connect(TIdPeerThread *AThread)
{
TClient *pClient = NULL;
AnsiString ABuffer, text;
AnsiString PeerIP = AThread->Connection->Binding->PeerIP;
TDateTime TimeConnected = Now();
ABuffer = AThread->Connection->ReadLn();
if((ABuffer.Pos("TT") == 0) && (ABuffer.Pos("IG") == 0) && (ABuffer.Pos("RR") == 0))
{
text = AnsiString().sprintf("1>>> Unknown(%s) on %s connected illegal!...",
PeerIP, DateTimeToStr(TimeConnected));
WriteMsg(text);
AThread->Connection->Disconnect();
return;
}
if(ABuffer.Pos("IG") != 0)
{
pClient = new TClient;
pClient->PeerIP = PeerIP;
pClient->HostName = Clients[eIG];
pClient->Id = eIG;
AThread->Data = (TObject *)pClient;
AThread->FreeOnTerminate = true;
// Report client is on line
}
text = AnsiString().sprintf("1>>>%s(%s) on %s on line!...",
pClient->HostName, PeerIP, DateTimeToStr(TimeConnected));
WriteMsg(text);
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::IdTCPServer1Disconnect(TIdPeerThread *AThread)
{
TClient *pClient = NULL;
AnsiString Msg;
if (IsClosing) return;
pClient = (TClient *)AThread->Data;
if(pClient->Id == 1)
{
// Report client is off line
Msg = AnsiString().sprintf("1>>>%s(%s) on %s off line...",
pClient->HostName, pClient->PeerIP, DateTimeToStr(Now()));
WriteMsg(Msg);
}
delete pClient;
AThread->Data = NULL;
AThread->Terminate();
try
{
IdTCPServer1->Threads->LockList()->Remove(AThread);
}
__finally
{
IdTCPServer1->Threads->UnlockList();
}
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TClient *pClient;
if (!AThread->Terminated && !IsClosing)
{
pClient = (TClient *)AThread->Data;
if((pClient != NULL) && (pClient->Id != 0))
{
try
{
if(pClient->Id == 1)
{
// Report client still alive
}
}
catch(Exception &E)
{
if (!IsClosing)
{
if(!AThread->Stopped)
{
AThread->Stop();
AThread->Connection->Disconnect();
}
}
}
}
}
}
Client side
void __fastcall TSocketThread::Execute()
{
unsigned long ulCheckSum;
SIM_SVR1_ACK_STRUCT Ack2Svr;
SIM_SVR_DATA DataFromSvr;
int Counter;
memset(&DataFromSvr, 0, sizeof(DataFromSvr));
memset(&Ack2Svr, 0, sizeof(Ack2Svr));
Counter = 0;
// fetch and process commands until the connection or thread is terminated
while (!this->Terminated && FSocket->Connected())
{
try
{
// recieve data from server
FSocket->ReadBuffer(&DataFromSvr, sizeof(DataFromSvr));
// check CRC
ulCheckSum = CRC_32((unsigned char*)&DataFromSvr.SimData, sizeof(DataFromSvr.SimData));
if (ulCheckSum == DataFromSvr.uiCheckSum)
{
FSmIpcUtil->Writeto(&DataFromSvr.SimData, DATA_OFFSET, sizeof(DataFromSvr.SimData));
}
else
{
// counter to record error
Synchronize(UpdateCaption);
}
// read return from local SM
FSmIpcUtil->Readfrom(&Ack2Svr, ACK_OFFSET, sizeof(Ack2Svr));
FSocket->WriteBuffer(&Ack2Svr, sizeof(Ack2Svr));
if (DataFromSvr.SimData.SimIgTgt.Acdata.iSimStatus == 11)
{
Terminate();
FSocket->Disconnect();
PostMessage(Application->Handle, WM_SHUTDOWN, 0, 0);
Sleep(500);
}
}
catch (EIdException& E)
{
this->Terminate();
FSocket->Disconnect();
}
}
}
There are several issues with your code.
A multimedia timer callback is very restricted in what it is allowed to do:
Applications should not call any system-defined functions from inside a callback function, except for PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.
If transmission speed is important, don't have the timer callback do the broadcasting at all. Save the data somewhere safe, and then have each TIdTCPServer thread grab the latest data on its own time. This also keeps each connection thread isolated so one connection cannot affect any other connection if problems occur.
DO NOT set the TIdPeerThread::FreeOnTerminate to true, DO NOT call TIdPeerThread::Stop(), DO NOT manually remove threads from the TIdTCPServer::Threads property. You do not own the threads, TIdTCPServer does, and it will manage them for you. If you want to stop a given thread, closing the thread's socket is all you need to do. But by moving all of the sending logic into OnExecute where it belongs, you can let TIdTCPServer handle any errors and close the socket for you.
Your OnConnect event handler is setting AThread->Data only if an IG client connects, but your OnConnect and OnDisconnect handlers are not checking for that condition before attempting to access the TClient object.
Your OnDisconnect event handler is leaking memory if IsClosing is true. And it is calling Threads->UnlockList() without calling Threads->LockList() first. Attempting to unlock the list when it is not locked by the calling thread will cause errors and deadlocks.
Try something more like this:
struct TClient
{
AnsiString PeerIP; //{ Client IP address }
AnsiString HostName; //{ Hostname }
int Id; //{ Client ID }
};
void CALLBACK mmTimerProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
TfmMain *pMain = (TfmMain *)dwUser;
if (pMain->IsClosing || pMain->Shutdown) return;
pMain->UpdateServer1Data();
// make sure pMain->Data2Client is thread-safe...
// set a signal that Data2Client has been updated...
// Shutdown computer or close application
if (pMain->SimIos.Status.iSimStatus == 11)
{
pMain->Shutdown = true;
pMain->CloseApp();
}
}
void __fastcall TfmMain::IdTCPServer1Connect(TIdPeerThread *AThread)
{
TClient *pClient;
AnsiString ABuffer, text;
AnsiString PeerIP = AThread->Connection->Binding->PeerIP;
TDateTime TimeConnected = Now();
ABuffer = AThread->Connection->ReadLn();
if ((ABuffer.Pos("TT") == 0) && (ABuffer.Pos("IG") == 0) && (ABuffer.Pos("RR") == 0))
{
text = AnsiString().sprintf("1>>> Unknown(%s) on %s connected illegal!...", PeerIP.c_str(), DateTimeToStr(TimeConnected).c_str());
WriteMsg(text);
AThread->Connection->Disconnect();
return;
}
pClient = new TClient;
pClient->PeerIP = PeerIP;
if (ABuffer.Pos("IG") != 0)
{
pClient->HostName = Clients[eIG];
pClient->Id = eIG;
}
else
pClient->Id = 0;
AThread->Data = (TObject *)pClient;
// Report client is on line
text = AnsiString().sprintf("1>>>%s(%s) on %s on line!...", pClient->HostName.c_str(), PeerIP.c_str(), DateTimeToStr(TimeConnected).c_str());
WriteMsg(text);
}
void __fastcall TfmMain::IdTCPServer1Disconnect(TIdPeerThread *AThread)
{
TClient *pClient = (TClient *)AThread->Data;
AnsiString Msg;
AThread->Data = NULL;
if (pClient)
{
// Report client is off line
Msg = AnsiString().sprintf("1>>>%s(%s) on %s off line...",
pClient->HostName.c_str(), pClient->PeerIP.c_str(), DateTimeToStr(Now()).c_str());
WriteMsg(Msg);
delete pClient;
}
}
void __fastcall TfmMain::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TClient *pClient;
if (IsClosing) return;
// make sure pMain->Data2Client is thread-safe...
if (Data2Client has been updated since last event)
{
AThread->Connection->WriteBuffer(&pMain->Data2Client, sizeof(pMain->Data2Client), true);
}
pClient = (TClient *)AThread->Data;
// Report client still alive
}

Filter DBGrid or Table Builder 6

In this form I am using Table1 (three columns “ZEMLJA", "KATEGORIJA" and "NAZIV”) with DataSource1 connected on paradox 7 database. Also DBGrid1 is connected to the DataSource1. Here is also three Edit box (Edit1, Edit2 and Edit3).
In header file I put:
public: // User declarations
__fastcall TForm4(TComponent* Owner);
void Filtriraj(AnsiString szZemljaAsterix, AnsiString szKategorijaAsterix, AnsiString szNazivAsterix, AnsiString szNoviAsterix);
My cpp file looks like this:
#include <vcl.h>
#pragma hdrstop
#include “Unit4.h”
//—————————————————————————
#pragma package(smart_init)
#pragma resource “*.dfm”
TForm4 *Form4;
//—————————————————————————
__fastcall TForm4::TForm4(TComponent* Owner): TForm(Owner)
{
}
//—————————————————————————
void TForm4::Filtriraj(AnsiString szZemljaAsterix, AnsiString szKategorijaAsterix, AnsiString szNazivAsterix, AnsiString szNoviAsterix)
{
AnsiString szUslov=””;
if( !Edit3->Text.IsEmpty() )
{
szUslov = “ZEMLJA = ‘” + Edit3->Text + szZemljaAsterix + “‘”;
}
if( (!Edit4->Text.IsEmpty()) && (!Edit3->Text.IsEmpty()) )
{
szUslov = szUslov + “and KATEGORIJA = ‘” + Edit4->Text + szKategorijaAsterix + “‘”;
}
else if( (!Edit4->Text.IsEmpty()) && (Edit3->Text.IsEmpty()) )
{
szUslov = “KATEGORIJA = ‘” + Edit4->Text + szKategorijaAsterix +”‘”;
}
if( !Edit5->Text.IsEmpty() )
{
if(szUslov!=””)
szUslov = szUslov + “and NAZIV = ‘” + Edit5->Text + szNazivAsterix + “‘”;
else
szUslov = szUslov + “NAZIV = ‘” + Edit5->Text + szNazivAsterix + “‘”;
}
Table3->Filter = szUslov;
Table3->Filtered = true;
}
//—————————————————————————
void __fastcall TForm4::Edit3Change(TObject *Sender)
{
Filtriraj(“*”,””,””,””);
}
//—————————————————————————
void __fastcall TForm4::Edit4Change(TObject *Sender)
{
Filtriraj(“”,”*”,””,””);
}
//—————————————————————————
void __fastcall TForm4::Edit5Change(TObject *Sender)
{
Filtriraj(“”,””,”*”,””);
}
//—————————————————————————
void __fastcall TForm4::Edit3KeyPress(TObject *Sender, char &Key)
{
if( Key==13 )
{
Edit4->SetFocus();
if(Edit3->Text==””)
Edit3->Text =””;
else
Edit3->Text = Edit3->Text + “*”;
Filtriraj(“”,””,””,””);
}
}
//—————————————————————————
void __fastcall TForm4::Edit4KeyPress(TObject *Sender, char &Key)
{
if( Key==13 )
{
Edit5->SetFocus();
if(Edit4->Text==””)
Edit4->Text =””;
else
Edit4->Text = Edit4->Text + “*”;
Filtriraj(“”,””,””,””);
}
}
//—————————————————————————
void __fastcall TForm4::Edit5KeyPress(TObject *Sender, char &Key)
{
if( Key==13 )
{
DBGrid1->SetFocus();
if(Edit5->Text==””)
Edit5->Text =””;
else
Edit5->Text = Edit5->Text + “*”;
Filtriraj(“”,””,””,””);
}
}
//—————————————————————————
This code works great, each edit box filtering DBGrid correcly and also if I wanna put just a part of word which a want it works perfectly, but this filter works from the begining of the cell in DBGrid.
I wanna make a filter which one will find word everywhere in cell. For examle I have a lot of rows that means a lot of cells, in one cell is written “I WILL GO TO THE SCHOOL TOORRROW”, when I type in Edit box SCHOOL it should find me word SCHOOL in my cell and show me that in some way doesn’t matter how (row selector or filter I dont care).
If someone knows easier way to solve this problem.
Try something more like this:
public: // User declarations
__fastcall TForm4(TComponent* Owner);
void Filtriraj();
#include <vcl.h>
#pragma hdrstop
#include “Unit4.h”
#include <StrUtils.hpp>
//-------------------------
#pragma package(smart_init)
#pragma resource “*.dfm”
TForm4 *Form4;
//-------------------------
__fastcall TForm4::TForm4(TComponent* Owner)
: TForm(Owner)
{
}
//-------------------------
String AddWildcardsAndQuotes(String S)
{
if( !S.IsEmpty() )
{
if( !AnsiStartsText("*", S) )
S = ("*" + S);
if( !AnsiEndsText("*", S) )
S += "*";
}
return QuotedStr(S);
}
//-------------------------
void TForm4::Filtriraj()
{
String szUslov;
if( Edit3->GetTextLen() > 0 )
{
szUslov = ("ZEMLJA = " + AddWildcardsAndQuotes(Edit3->Text));
}
if( Edit4->GetTextLen() > 0 )
{
if( !szUslov.IsEmpty() )
SzUslov += " and ";
szUslov += ("KATEGORIJA = " + AddWildcardsAndQuotes(Edit4->Text));
}
if( Edit5->GetTextLen() > 0 )
{
if( !szUslov.IsEmpty() )
szUslov += " and ";
szUslov += ("NAZIV = " + AddWildcardsAndQuotes(Edit5->Text));
}
Table3->Filter = szUslov;
Table3->Filtered = !szUslov.IsEmpty();
}
//-------------------------
// common OnChange handler assigned to Edit3, Edit4, and Edit5
void __fastcall TForm4::EditChange(TObject *Sender)
{
Filtriraj();
}
//-------------------------
// common OnKeyPress handler assigned to Edit3, Edit4, and Edit5
void __fastcall TForm4::EditKeyPress(TObject *Sender, char &Key)
{
if( Key == VK_RETURN )
{
Key = 0;
// make sure each control's TabStop is true and its TabOrder
// is logical, eg: Edit4->TabOrder is Edit3->TabOrder+1,
// Edit5->TabOrder is Edit4->TabOrder+1, and
// DBGrid1->TabOrder is Edit5-TabOrder+1
//
this->SelectNext(static_cast<TEdit*>(Sender), true, true);
Filtriraj();
}
}
//-------------------------
Update: alternatively:
String AddWildcardsAndQuotes(String S)
{
if( !S.IsEmpty() )
{
S = StringReplace(S, "*", "%", TReplaceFlags() << rfReplaceAll);
S = StringReplace(S, "?", "_", TReplaceFlags() << rfReplaceAll);
if( !AnsiStartsText("%", S) )
S = ("%" + S);
if( !AnsiEndsText("%", S) )
S += "%";
}
return QuotedStr(S);
}
//-------------------------
void TForm4::Filtriraj()
{
String szUslov;
if( Edit3->GetTextLen() > 0 )
{
szUslov = ("ZEMLJA LIKE " + AddWildcardsAndQuotes(Edit3->Text));
}
if( Edit4->GetTextLen() > 0 )
{
if( !szUslov.IsEmpty() )
SzUslov += " and ";
szUslov += ("KATEGORIJA LIKE " + AddWildcardsAndQuotes(Edit4->Text));
}
if( Edit5->GetTextLen() > 0 )
{
if( !szUslov.IsEmpty() )
szUslov += " and ";
szUslov += ("NAZIV LIKE " + AddWildcardsAndQuotes(Edit5->Text));
}
Table3->Filter = szUslov;
Table3->Filtered = !szUslov.IsEmpty();
}
AnsiString query;
Query1->Close();
Query1->UnPrepare();
Query1->SQL->Clear();
query="SELECT NAZIV FROM \"C:\\Users\\work\\Desktop\\New folder\\publiks.DB\" Publiks WHERE NAZIV LIKE'%" +Edit1->Text+ "%' ORDER BY NAZIV";
Query1->SQL->Add(query);
Query1->Prepare();
Query1->Open();
I solved for one Editbox and column from Table using Query it works that does it means paradox support LIKE

Directx Window keeps Crashing

My problem with this code is that when I run it in visual C++ A window pops up
but then it just crashes. It is not responding and I cannot click exit. I have to pull up the
task manager to get rid of the window. I am new to windows programming and direct X.
Below I will post were I think the problem is.
#include <d3d9.h>
#include <time.h>
#define APPTITLE "Direct3D_Windowed"
LRESULT WINAPI WinProc(HWND, UINT, WPARAM, LPARAM);
ATOM MyRegisterClass(HINSTANCE);
int Game_Init(HWND);
void GAME_RUN(HWND);
void GAME_END(HWND);
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
// Over here, after GAME_END() is called, I tried separating the POSTQUITMESSAGE But I
I just got an error.
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg )
{
case WM_DESTROY:
GAME_END(hWnd);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
return RegisterClassEx(&wc);
}
// I got this code from a book that I am reading and realized that WinProc is not being
called in this function. Is this the potential problem? Were would I put the WinProc
function call if it is supposed to be here in WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg = {0};
MyRegisterClass(hInstance);
HWND hWnd;
hWnd = CreateWindow(
APPTITLE,
APPTITLE,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
400,
NULL,
NULL,
hInstance,
NULL);
if(!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
if(!Game_Init(hWnd))
return 0;
int done = 0;
while(!done)
{
if(msg.message == WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
MessageBox(hWnd, "Recieve WM_QUIT message", "WinMain", MB_OK);
done = 1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
GAME_RUN(hWnd);
}
return msg.wParam;
}
int Game_Init(HWND hWnd)
{
MessageBox(hWnd, "Program is about to start", "Game_Init", MB_OK);
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if(d3d == NULL)
{
MessageBox(hWnd, "Error initializing Direct3D", "Error", MB_OK);
return 0;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
if(d3ddev == NULL)
{
MessageBox(hWnd, "Error creating Direct device", "Error", MB_OK);
return 0;
}
srand(time(NULL));
return 1;
}
void GAME_RUN(HWND hWnd)
{
if(d3ddev == NULL)
return;
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 255, 255), 1.0f, 0);
if(d3ddev->BeginScene())
{
d3ddev->EndScene();
}
d3ddev->Present(NULL, NULL, NULL, NULL);
}
void GAME_END(HWND hWnd)
{
MessageBox(hWnd, "Program is about to end", "Game End", MB_OK);
if(d3ddev != NULL)
d3ddev->Release();
if(d3d != NULL)
d3d->Release();
}
Have a look at this?
if(msg.message == WM_QUIT)
In your while-loop.
Perhaps change that to, say:
if(true)
Reason: you want your application to pass on all messages, not just the ones that cause it to quit. Say for instance when windows wants your application to draw itself. Basically, your current code doenst allow your application to do anything except quitting.
If you want to do something special when the application quits, add another case WM_QUIT: after the already existing case WM_DESTROY: in WinProc().
The current location for GAME_RUN(hWnd); will not work out for you.
You want to either put that in a seperate thread (easiest, and highest performance). Or you want to use some timers, and handle it with case WM_TIMER: after your case WM_DESTROY:. Or alternatively make up your own user defined message.

Resources