How to lock on to a cloned form in Delphi? - forms

I am writing a chat program that has a bunch of clients connect to it and populate themselfs to a listview, I want to be able to click on each individual client and open up a form that looks like a chat, but I want to be able to do it to multiple clients at the same time.
I have made Form2 (the chat window) clone itself for every instance, however I need to know how to lock on to the cloned form to make changes such as Form2.RichEdit.Lines.Add
However when I try to do this it does not work because I'm not locking on to the right form since it is cloned I am assuming it is no longer Form2
Any info on this would be highly appreciated.
Update
I am going to go ahead a reword what I am trying to do.
I will explain what im trying to do: I have a chat program (server) that is listening for clients to connect via Indy10 sockets When the client connects it populates the ListView with the user name and when I click on the user name (the server) opens privatemessageform where I can chat with the client.
I want to be able to have multiple clients connected and I want to be able to click on as many as I want and have it clone the privatemessageform and have 2 separate chat windows to 2 separate clients
The problem is: When trying to click on the seccond user the program gets confused and cannot lock on to that seccond user's privatemessageform (clone).
And if any more info is needed and I mean anything at all please do not hesitate to ask I will be on for several hours and constantly checking this thread.
I've been stuck on this for 3 days so I would really love to get this resolved and move forward with my project. Any information is highly appreciated. Thanks in advance!

Open Project Options and remove Form2 from auto-creation list. Do not use that variable any more.
Rename TForm2 to some meaningful name. Once you would have ~10 forms in your program you would forget what you meant by numbers 2, 5, 7 ...
ALWAYS give variables meaningful names, that includes components, that includes forms. Here i will name TForm2 a TPrivMessageForm
Use a special array of variables to keep several forms, not a single global variable. For example like that:
Type TChatUser = string;
// to begin with, user is a name. Then it may become URL, or GUID or something
// complex like `record` or `class` or whatever
Type TPMForms = TDictionary<TChatUser, TPrivMessageForm>;
PMForms := TPMForms.Create;
Creating new private message window after clicked on user:
if not PMForms.ContainsKey(ClickedUser)
then PMForms.Add(ClickedUser, TPrivMessageForm.Create(Application) );
PMForms[ClickedUser].ChatWith := ClickedUser; // variable in ex-TForm2 to tell several instances apart
When such form is closed - it should via its OnClose
Remove itself from PMForms list (so no dangling pointers would remain)
chose caRelease for closing actions (making VCL actually free the form object)
See Also
http://delphi.about.com/od/beginners/a/using-t-dictionary-hash-tables-in-delphi.htm
http://docwiki.embarcadero.com/CodeExamples/XE4/en/Generics_Collections_TDictionary_(Delphi)
PS. Edit your question please and add TAG with your specific Delphi version.
PPS. download ready-made FLOSS chat programs and just read and learn how they do it. Maybe instead of opening a free-floating (cluttering desktop) form you'd better open Tab in PageControl. "Use the Source, Luke"
https://sourceforge.net/p/dreamchat/wiki/Home/
https://sourceforge.net/p/achat/wiki/Home/
http://www.visualirc.net/features.php
For the latter to find the sources one has to type two words "Visual IRC" at www.google.com and get http://sourceforge.net/p/visualirc/mercurial/ci/default/tree/ - this crucial information i did omitted in fair belief that a person interested in finding sources would be able to do it on his own.
PPPS. Those is not "cloned": cloned are separated objects. What you talk is several instances of the same form class. Like you may have two or more labels on the form, you can have two or more forms in your application.

Related

How to transfer Files from OPC UA Client to Server

I want to Download and Upload, for example a .txt file, with the UA-Expert Client to/from a Server which i have set up on a Device.
Could someone provide me a Step by Step solution or an example on how to implement this?
I first followed the tutorials from the open62541 website.
I tried to follow and understand the OPC-UA-Specifications, particularly Part 5 Annex C.
Thank you in Advance.
open62541 doesn't support this out of the box meaning that there is no pre-made plugin which implements the required Objects for the various platforms.
That said it isn't to much work to do it yourself (especially if you don't need something generic/cross platform).
I've done such a one-off a few months ago. It was like 2 days of work. It was limited to downloading specific files from the server.
If my memory serves me well all you need to do is to enable the generation of the types specified by part5/annex c (there is a .txt or .csv in the sourcetree containing all the types that should be generated), after that you need to instantiate such an object (File for example) and place it somewhere in your server address space. What is left to do is to implement the various methods (open, read, ...) And to hook up your objects with callbacks to these.
This feature was added recently, but is not yet included into the official release.
Have a look at: https://github.com/opcua-tsn-team-kalycito/open62541/tree/fileType_object_implementation
(Make sure to use the commit 76eb14f6886911f954c40492cbe346c69b055ba5; the latest commit is not working)
An example implementation is:
UA_StatusCode result = UA_Server_addFile(server, FileTypeNodeId,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1, "Sample File"),
oAttr, filePath, NULL, NULL
);

Adding block feature using swift and parse server

So I'm dealing with app rejection "Guideline 1.2 - Safety - User Generated Content" and one of the features app want me to implement is "- A mechanism for users to block abusive users" Im not sure exactly how to put the code into action but know what i have to do which is
Step 1. Create class in Parse for blocked users, like: "Blocked"
Step 2. Create columns of type [String]: blockedBy & username (user is blocked)
Step 3. Query only users if current user is not in blocked list
Step 4. Add button to send PFObject to block a User
If someone can help i can provide info from my project. It would be much appreciated because I've been struggling with this for weeks.
Check out https://www.raywenderlich.com/98831/parse-tutorial-getting-started-web-backends tutorial. Great help, shows how to setup the local environment, the MongoDB, how to create a class within the local parse environment ran from the terminal, shows how to query, etc. Let me know if you have more specific questions I can help resolve.

External access to Magento instances

I've started investigating alternatives to my project and a few questions came out that I couldn't answer by myself.
The problem is: I want to create a web page able to access multiple Magento instances installed in the same server. Currently, I have one Magento instance per client and this project will access several Magneto instances to export reports from each one (for example).
The alternatives I thought til this moment are:
Have another Magento instance, create a new module within it that changes its 'database target' before triggering operations/queries;
Questions until this moment:
Can I 'change the database target' of a Magento instance?
How can I access data from a Magento instance without appeal to SOAP/REST?
I want to re-use some components (grids, tabs, forms..) from Magento, that's why I'm not considering an independent project (Zend, for instance) that can access this code from another projects. Does it make sense?
Any other idea?
==Edited==
Thanks by the tips and sorry by my ignorance. The comments let me believe that I'm able to execute something like this:
// File myScript.php
require '/home/DOMAIN1/app/Mage.php';
Mage::app('default');
// get some products from DOMAIN1
require '/home/DOMAIN2/app/Mage.php';
Mage::app('default');
// get some products from DOMAIN2
Is it right? Can I execute require twice (and override things from first require)?
==Edited2==
I'm still trying to connect to several Magento instances from a single third party file. Is there any tip? I'm facing several/different errors at this moment.
The only thing I know is that I can still rely on SOAP to get the information I need, but this will be expensive.
Thanks!
The easiest way would be to include Mage.php from each shop instance. You would need to use namespaces or some other trickery to be able to load more then one.
Or if that doesn't work - make your own API in a separate file to get what you want from one shop, and combine the results in the PHP-file that calls the API.
Here's a sample on how to use Magento functionality outside of Magento:
require 'app/Mage.php';
if (!Mage::isInstalled()) {
echo "Application is not installed yet, please complete install wizard first.";
exit;
}
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
// your custom code here, for example, get the product model..
$productModel = Mage::getModel('catalog/product');

How can I restore the synchronization between the auto-create forms list and the DPR initialization code?

I have a D2006 app in which the DPR file has had numerous edits (yes, I know - you shouldn't mess with the DPR file) to accommodate such things as a splash screen, preventing a second instance of the app being started, handling of command line options that need to be processed before any forms are created, etc.
One day, I noticed that the auto-create forms list in the project options is empty - but the DPR file still has the code in there to create some of the forms.
If I try to restore all the forms that should be auto-created from the dialog, it complains Error - Call to Application->CreateForm is missing or incorrect and doesn't do anything.
How can I restore this connection - apart from rebuilding the DPR from scratch?
is it safe to manually add the CreateForm calls?
are there any documented rules as to what you can do in the DPR file?
I have a suspicion that try..except and if..else clauses in the DPR upset Delphi. Will moving as many functions as possible to a separate unit and calling them be helpful?
I haven't really seen any documented rules as to what you can do in the DPR file, because I guess there are no strict rules.
The problem begins when you create a "Forms" application. (No problems with console or non-GUI applications I've noticed).
The IDE will automatically change the DPR any time you add a new Form or a DataModule to it, by assuming you want to auto-create them.
This can mess up your DPR, if it has a lot of code/compiler-directives/if-blocks/try-catch blocks etc...
So I'll tell you what my rules are, and in a short line:
Keep it as simple as you can.
My DPR contains only a call to some init code and auto creates the main form only:
MyAppInit; // in AppInit unit
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
However in the uses section I add (or keep what the IDE added) all the forms my application uses (and also application related units) - this is useful when I want to view->forms or view-units.
In-fact when I add a new form to the application, the first thing I do is go the DPR and remove the line:
Application.CreateForm(TMyNewForm, MyNewForm);
NOTE (EDIT): The IDE can be configured to NOT auto create forms (No Application.CreateForm entry will be created in the DPR). In older version of Delphi this option is under: Tools/Environment Options/Preferences -> Auto create forms. In newer versions: Tools/Options/VCL Designer/Module creation options -> Auto create forms & data modules.
At run-time, I create all my forms dynamically when I need them, and destroy them when they no longer needed. DataModules/Splash (etc...) are created on the MainForm.OnCreate event.
This method has worked for me nicely for the past few years maintaining a large scale DB application. This will probably not cover all cases, but it worked fine for my needs.
P.S: "Is it safe to manually add the CreateForm calls" - Yes. But think twice if you really need them to be auto-create by the application.
IMHO You don't really need that AutoCreate forms from Delphi, but maybe in the casual test project.
And the dpr is just another source code file, where you're meant to write code to make things happen (or prevent it to happen), so don't worry if you lost that sincronization, which IMHO is buggy if can't read your pascal code to work properly.
If you still want to create some forms from the DPR, add the Application.CreateForm or TMyForm.Create calls manually to the file, AFAIK there's no rules against doing it that way.
Since Delphi owns the .DPR, I put my startup logic into a separate unit for each project.
That works really well, only very few entries need to be in the .DPR.
Since that unit controls the Application.CreateForm logic too, the IDE has an empty list for that: I'm fine with that.
The only things left in the .DPR are:
the big uses that indicates which modules are part of your project
a call to Main in the startup logic unit

Access 2010 Form.Repaint - Hanging

I'm hopefully missing something obvious here...
I have just kicked off developing a new Access 2010 application. Something personal and hopefully simple.
The first thing I need to do is read a bunch of files off of the hard drive. I parse the contents adding the information to a table if it doesn't already exist.
Code works fine, that's not the issue. As it can take a while I've added a simple progress dialog using a standard form but in dialog/popup mode. As the For Each loop of the FSO.Folder.Files object is progressed I send some information to a couple of text boxes and issue a Me.Repaint (have also tried DoCmd.RepaintObject acForm, "FormName").
The issue is that I can get anywhere from 5% to 35% of the process complete before the repaints stop responding. The form only repaints when it gets to 100%.
The process uses limited recursion - if there is a subfolder - it calls itself to process that subfolder, but the folder structure is fairly linear so not many of those.
There are nothing bound to the form. All table updates happen in code and via RecordSets.
Any ideas why Access stops responding?
Cheers,
Roy
Add DoEvents after Repaint. That will cause Access to yield to Windows, which will can then handle its pending tasks ... such as updating the display in this case.
Actually, if your code updates text boxes, I don't see why you need to Repaint the form in order to display the changes. Try something like this instead ...
Me.MyTextBox = "hello"
DoEvents