Jump to content

wprins

uniGUI Subscriber
  • Posts

    151
  • Joined

  • Last visited

Everything posted by wprins

  1. In general it would be beter yes (actually having them in the body (POST) be better still perhaps IMHO). But UniGUI seems to use GET for the client side event propagation for whatever reason (instead of POST). Also in my particular case I don't have the luxury of passing parameters any way other than via URL. (It is a green screen application displaying the URL, with the terminal emulator being able to recognize a URL and launch the browser from it. Using headers or POST in this context would unfortunately require more smarts from a piece of software I don't control.) Thanks for the comment though, in the more general case I would be very much interested to know how to pass them via header or via POST (if possible.)
  2. As a possible alternative workaround, what is the most effective way to copy a file into the UniGUI cache and obtain the relevant URL to hand to a TUniGUIURLFrame? (Though copying every file into the UniGUI cache would not be my preferred solution due to the duplication and overheads of having possibly multiple copies of files lying around...)
  3. Hi, I want to serve up files from non UniGUI server based locations (or maybe even dynamic generation), kind of web-service style. The background is that we need the UniGUI client's browser to directly download or access files and data from locations NOT directly under where the server is running. These files need to be made available in the short term via the UniGUI app I'm working on, initially via direct "download". For example, PDF documents (or excel, or word, or whatever) that should be served to the client browser, as simple downloads. (I'm aware of the Gnostice StarDocs option and will be looking into this for a more seamless "in application" viewing approach, but in the meantime though it ought to be possible to just "directly" serve up files to the client/browser, where the document/file is not a location "under" the UniGUI server, or as I've said, may potentially not exist as a file at all but might be generated on the fly.) I've looked at the relevant demo's and there's obviously the PDF viewer demo, which however relies on the correspondence between "UniServerModule.FilesFolderPath" and "UniServerModule.FilesFolderURL) to effectively directly serve up PDF's hosted in a "known" location to the TUniURLFrame. Again, this works because you can construct a URL that corresponds to a location accessible underneath the UniGUI server and pass this to the TUniURLFrame. But what if this is not the case? That is, what would be the best UniGUI way to in effect "proxy" the file access request and return (in effect), say, a filestream from a location or source determined/managed by the UniGUI service? For example under Web Broker, one could generate what appears to be a file response on the fly, by handling the Response yourself in the relevant "OnAction" handler in the WebModule (kind of the equivalent of the UniGUI MainModule), doing e.g. something like the following in the relevant Action' OnAction() handler: //Web Broker style of dynamic generation of data that looks like file download to browser Response.CustomHeaders.Values['Content-Disposition'] := 'attachment; filename='+FormatDateTime('yyyy-mm-dd', SelectedDate)+'.csv'; Response.ContentStream := TStringStream.Create; {dump some stuff into TStringStream} Response.SendResponse; Handled := True; Similarly if this was a Datasnap server, one could presumably (not tested) do something similar using a TDSHTTPServiceFileDispatcher component and overriding the handling in BeforeDispatch(), where you are also given the Response object and have the opportunity to set Handled to True. Is there a component or a way to allow similarly overriding request processing from withing a user's session (e.g. not from the server's perspective -- it has OnHTTPCommand and OnHTTPDocument but these are not session/user specific so doesn't help here)? In an ideal world I'd have access to the Request and Response objects (like in DataSnap, WebBroker or Indy) from the context of the MainModule "OnHandleRequest" event. As it stands, unless I've missed something, in the MainModule's OnHandleRequest() event, while you are handed a reference to the relevant Session object (as a TObject, presumably castable TUniGUISession), it however doesn't seem to expose a way of directly handling/overriding/modifying the underlying HTTP Response object as outlined above (though there is a "Handled" var parameter...)? Thanks!
  4. Pas un Français ici, mais peut-être nous pouvons parler assez bien via Google Translate. Il a amélioré de façon spectaculaire au cours des derniers mois que vous devriez trouver si vous essayez. (Pour être clair, je ne peux pas parler français, cette réponse est la traduction de Google de ma réponse en anglais.)
  5. Is there a way to do this with the "normal" components (e.g. not the StarDocs "in the cloud" service) or is it possible to host the server side that renders/serves the document yourself? Not really sure I like the fact that documents have to be pushed/uploaded to Gnostice in order for this to work...
  6. I've set up processing to to look for and capture parameters passed via the URL (e.g. GET parameters, captured in MainModule.BeforeLogin, then deal with login/auth etc, and then used later etc.) However, the URL parameters stay on the browser address. I'd like to remove them after capture but I'm not sure how to get this effect in the browser. I assume I'd have to inject some JS at some suitable point (perhaps using UniSession.AddJS()?) With plain javascript one could do e.g. <html> <head> </head> <body> <div id="urldiv"></div> <script type="application/javascript"> var urldiv = document.getElementById('urldiv'); urldiv.innerHTML = '<p>Page opened with: '+window.location+'</p>'; window.history.replaceState({} , '', window.location.origin + window.location.pathname ); urldiv.innerHTML = urldiv.innerHTML + '<p>Location changed to: '+window.location+'</p>' </script> </body> </html> Opening this page with e.g. ?foo=bar will result in the query params being removed from the URL in the browser without a page reload. (I have a feeling this ought to be possible without too much fuss, and have hunted around the demos and so on to try and find an example, and have also some small amount of time inspecting e.g. UniSession but it's not been obvious what to do where, apologies if I've missed the obvious.)
  7. The whole "Handled" idea crops up in several places in Delphi (WebBroker, Indy, Datasnap IIRC offhand), usually in the context of some type of request event handler (web request), the idea being that, instead of letting the framework or library code "handle" the request in the normal way, you can (in the event handler), "intervene" and "handle it yourself", and signal this to the rest of the system/library by setting the "Handled" output parameter to True. In your case, you've basically handled the response, by setting the Content and ResponseCode, and also sent it off, which means you've literally handled it there and then, and should not want the rest of the normal processing to happen. To ensure that, you ought to therefore set Handled to True. (Sometimes one just wants to alter or augment, or inspect [or log] a request in an event handled, and you still want the "normal" library/framework processing to happen. In such cases you obviously would not set Handled to true.) Anyway I'll also be looking at file uploads to a UniGUI solution shortly so will come back post once I've had a look if you like.
  8. Could you clarify what you ought to do in BeforeLogin() to effectively customize/tailor the display (main form) successfully from within BeforeLogin() as it is not working as I anticipated. Currently I do simply this: // Pseudocode of what I do procedure TMainModule.UniGUIMainModuleHandleRequest(ASession: TObject; var LUniGUIApplication : TUniGUIApplication; begin LUniGUIApplication := TUniGUIApplication(UniApplication); if LUniGUIApplication.Parameters.GetText <> '' then begin // Check params on URL etc. Authentication/authorization etc... if valid then begin MainForm.Setup(......) MainForm.Show; Handled := True; end; end; ///... end; The expectation is that instead of opening the login form as normal, the system would show the main form directly after setting up accordingly as per the parameters etc. However what I'm seeing is that the main form is displayed in its initialized state. It's as though after calling my setup routines above, the main form is recreated or reinitialized. I've looked at moving the logic to "OnHandleRequest()" but that is evidently wrong as it breaks it more fundamentally. What am I missing/doing wrong?
  9. Thanks, I had missed the MainModule.BeforeLogin event, I'll use that. Agree about the security considerations and other points you make, though if one explicitly accepts that responsibility then it ought still be possible to do this I'd argue. There would need to be some sort of authentication & authorization check for such requests, no different to what one might demand in a normal stateless web based system faced with a request which obviously faces the same concerns w.r.t data and concurrency that you raise, where every request in principle need to be authenticated as allowable or not. Concretely, UniGUI is stateful (for obvious reasons) and uses sessionid's of some sort to associate requests with the state on the server, I don't know the details (nor have I looked), and I don't know what else it may or may not be doing to reauthenticate/validate incoming requests as valid for a specified/requested sessionid. I assume it is (unfortunately) a "black box detail" at the moment, and that implementation constraints may make making submissions against an existing session outside of the UniGUI browser JS problematic, though I'd argue in principle it need not necessarily be this way. That is to say I was hoping there would be a simple way to directly push a notification into an existing UniGUI server/session (somehow) to basically affect/update/change an existing (already open) page for a specific user (ergo, integration, notification generated from another system.) But lacking this I'll consider other options and see if rolling my own in some way is feasible. Offhand (thinking out loud) I though of adding a DS client in the UniGUI server [ugh] to use its callback functionality perhaps, or perhaps look into WAMP/Autobahn/Websockets (which I've been wanting to do for some time), via perhaps the esegece Delphi websockets components (which implement WAMP compliant client and server components), though I'd rather not introduce more third party components... but I digress. Thanks again for your response!
  10. For automation and integration it would be useful to be able to be able to post directly to a running session to affect it's state. How might one accomplish this? That is to say, if one considers the UniGUI server as a web service, how might one post to it to affect it in some way? Suppose a user has a browser page already open, viewing an existing UniGUI session. It should be possible to (somehow) identify the session and do a direct POST (from another browser page) or a third party system to for example open a new page or open a new customer (say). For a conventional Windows application similar could be achieved on one machine via posting Windows message, or across a network by having the application listen on a port for messages etc. Additionally (though this is perhaps worth a separate question), what if a new session is to be created? I can imagine perhaps examining some params passed on URL in LoginForm FormShow() and then directing the automatic logon and interpreting of commands from there. Though it seems a bit smelly that this logic/responsibility must be handled in the login form(?)
  11. Shouldn't you be setting "Handled" to True if you're handling the request yourself and writing the content to prevent downstream processing from happening? But, I'm also interested in this (and/or really something perhaps similar/related to this) which is how to control or post to a specific user session, I'll probably be posting a question shortly.
  12. Not particularly, thanks for the suggestion. (I wish Embarcadero would give the VCL image handling/buttons etc a once over as this type of thing is quite naff really...)
  13. 1) I am trying to use icons from here: https://material.io/icons/ When clicking on the "Glyph" property in Delphi and then Clicking "Load" and selecting a PNG sourced from there, the image is loaded and displayed but when you then click OK, an error message "Invalid graphic format" is displayed with call stack as follows: http://i.imgur.com/wiOns0Z.png The same happens with a conventional VCL TSpeedButton so it looks like some kind of Delphi bug, but mentioning just in case this is something UniGUI can do something about. 2) Additionally I notice TUniSpeedButton has "Images" and "ImageIndex" properties. I'd assumed that assigning a TUniImageList, populating it with PNG (which does work) and setting ImageIndex might cause the button to display the image but this appears to do nothing. Can you clarify whether this is supposed to work or why these properties appear to be ignored? Thanks Walter
  14. Is your Zebra printer connected to the UniGUI server or the client PC where the browser is running? And what is your expectation? Obviously as it stands the Zebra printer needs to be connected to the UniGUI server in order for printing to be possible. At which point, printing can be done (presumably) as explained here: http://stackoverflow.com/questions/18198820/delphi-printing-to-zebra-printer
  15. The ServerModule logs actiivty to a log file in a "log" folder when run as standalone server, both when run under the IDE (in which case it logs "Debug Mode = ON" as well). How can I disable (or otherwise control) this logging? (Apologies if I've missed something obvious)
  16. Thanks, that should be sufficient.
  17. Would it be possible to include multiple login forms in one application, each perhaps accessible via (say) distinct access URL? If so how? This would be to enable different types of personnel to be given a customer/themed/dedicated login page by user type. Thanks Walter
  18. What do you mean exactly that it doesn't work? If you mean it doesn't work in the respect of the global instances/references that is created by the IDE in a normal single user application then yes, that way of creating them doesn't work because it cannot work. Or at least, not just as naievely as with a single user application. Instead, you just need to create your objects (datamodules included) as needed from withing the main module. Remember that with a normal Delphi application you have essentially one user and one main thread of execution, so having a bunch of global datamodules and forms (even though that's actually dubious IMHO) can work. But with a UniGUI server you're serving multiple users, so to keep everyone out of each others hair you can't rely on single globally created instances for most things.
  19. wprins

    app execution

    Sorry I just see I've missed half the conversation (in particular Farshad's responses) so maybe my comments are erm, surplus to requirements. My apologies at self.
  20. wprins

    app execution

    However: Have you looked at the uniGUI\Demos\Desktop\BlockingModals\bmodal.dproj project? The left top button appears to do *exactly* what you want, that is, show a Modal form then return the value and process it Synchronously? The demo app has a note on the bottom saying: "In MainModule "EnableSynchronousOperations" property must be True". Might this be a simpler way for you to accomplish what you want? (That said, callbacks/asynchronous style of programming is very much becoming ever more relevant so it'd be very useful to wrap your head around it! )
  21. wprins

    app execution

    jahlxx, Write a sample VCL app that shows what you want, including the fact that it needs to be somewhat general. Then I'll (we'll) refactor it to do it asynchronously. But to also directly respond to a previous post of yours: First of all, just so I understand, are you basically trying to handle a lookup window, data entry, type of scenario? (That's what it sounds like to me!) So anyway, there's 2 ways that come to mind; 1) Pass the TUniEdit as parameter to the Modal form. When it closes it itself assigns the selected value to the TUniEdit previously passed. 2) As has been suggested: Refactor whatever code currently comes after the synchronous/linear ShowModal based code into a seperate procedure, such that this procedure expects the results of the Modal form to do its work. Then, you pass this procedure to the Modal call of the form. It then calls the procedure ("callback procedure"), passing in the values once the user confirm selection. And both of these suggestions are in some sense the same, and similar to what's already been suggested: you basically shift the code that must wait out of being embedded below a ShowModal call. Hope that helps? (Maybe I'll create a small sample...)
  22. Hi, I'm writing a frame for handling/displaying some images in the context of an application. Currently I'm using a TUniImage and doing a UniImage.Picture.LoadFromFile() to load the image. I also use UniImage.Stretched set to True (with Proportional being set to True also) to allow the image to always fit and be resized depending on the area available. I'm also allowing the image to be displayed at 100% resolution, that can in basic terms be achieved by simply setting UniImage.Stretched to False. However the image then obviously falls off the sides and bottom of the browser page and there's no way by default to either pan or scroll over the image and no scrollbars to allow this. (There's a "Draggable" property on TUniImage but this doesn't really do what is required.) What would be the best way to achieve this? I've briefly looked at TUniScrollbox and expected it to sprout scrollbars when housing an oversized image, but this didn't work. Not sure if I did something wrong or not in that attempt, but anyway does anyone have any advice regarding this? In short: What is the best way to basically load an image into a TUniImage with Streteched set to False, and then allow the user to pan/scroll around the image, in the context of another panel/form inside a UniGUI application? Thanks in advance, Walter
  23. That's not correct. The theme is per browser, effectively, so as long as users are on different browsers then they can have different themes. There's some feature (a cookie I assume) that ensures that the browser remembers its theme. So different users can certainly have different themes as long as they're not all on the same browser/pc, which presumably they're not going to be...
  24. Not sure if this is 100% what you want, but: Set MainModule.RecallLastTheme property to True, and then assign to MainModule.Theme at runtime when you want to change the theme. The user will have to log in again of course, but then the login form (and everything else) should come back with the new theme and will stay so until changed again. See also the AllFeatures\mdemo.dpr project which demonstrates the above, setting the theme with combobox.
  25. Well in that case a suggestion would be that you have (at least) 2 instances of your application on 2 separate servers. You then switch (via DNS, for example) users to using the new version on the "new" server and (eventually) shut down the "old" server after the last user (eventually) comes off or they time out, at which point you can upgrade it also.
×
×
  • Create New...