Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 04/20/20 in Posts

  1. David Heffernan

    Threading question

    A big part of your problem is trying stuff at random without any understanding of the reason why. You say that you find windows a swampy mess, but the code you presented here can be reasoned with quite easily if one has the knowledge, and it isn't that advanced. Unfortunately quite aot of the "advice" you have received has been incorrect. The only way for you to make progress is to stop guessing and trying random suggestions from people who don't understand the area. Get a stack trace with madExcept. It takes little time to add that.
  2. Stefan Glienke

    Difference between Pred and -1

    Fun fact: you can omit the 3rd argument of Copy if you just want to cut from the beginning.
  3. Dave Nottage

    Delphi fmx comes standard in iOS font

    I see what the problem is now: it's because selecting Segoe UI at design-time results in the Family value not being stored in the .fmx, because it's the default for Windows. I'd consider that a design fault, since it does not account for using a font with the same name on platforms other than Windows. Easiest solution: use something that looks like Segoe UI, but isn't 🙂 Any other solution would seem a bit difficult..
  4. Vandrovnik

    Variant to generic T, how?

    This compiles, but I have not tested, whether it works as expected 🙂 ToField<T> = class(tObject) private fData : T; protected procedure SetFromVariant(const aValue : Variant); end; procedure ToField<T>.SetFromVariant(const aValue: Variant); var val: TValue; begin val := TValue.FromVariant(aValue); fData := val.AsType<T>; end;
  5. I would rewrite that to something more like this instead. Don't duplicate code that doesn't need to be duplicated: var LCount: Integer; LCount := o.{$IFDEF JSONOBJ_HAS_COUNT}Count{$ELSE}Size{$ENDIF}; if LCount <> 3 then raise Exception.CreateFmt(_('Parsing error on JSON answer: Root object size is %d not 3.'), [LCount]); I would just write a class helper or separate function, and IFDEF the code inside of it. Class helpers were first introduced in Delphi 2005, but were buggy and not officially supported until Delphi 2006. JSON was first introduced in Delphi 2010.
  6. I'am reading calls from Android call log. Date format is something that Delhi don't recognise. Date is returned like this: "1587377791601". Any idea what this number means and how to get date and time from it? Here's code what works, i have commented out lines what i don't want use. In commented lines is (StringToJString(...)) but it must be ( TJCallLog_Calls.JavaClass....) : var cursor: JCursor; uri: Jnet_Uri; CACHED_FORMATTED_NUMBER, CACHED_LOOKUP_URI, CACHED_MATCHED_NUMBER, CACHED_NAME, CACHED_NORMALIZED_NUMBER, CACHED_NUMBER_LABEL, CACHED_NUMBER_TYPE, CACHED_PHOTO_ID, CONTENT_ITEM_TYPE, CONTENT_TYPE, COUNTRY_ISO, DATA_USAGE, DATE, DEFAULT_SORT_ORDER, DURATION, EXTRA_CALL_TYPE_FILTER, FEATURES, IS_READ, LIMIT_PARAM_KEY, NEW, NUMBER, NUMBER_PRESENTATION, OFFSET_PARAM_KEY, PHONE_ACCOUNT_COMPONENT_NAME, PHONE_ACCOUNT_ID, TRANSCRIPTION, TYPEX, VOICEMAIL_URI : integer; msgunixtimestampms:int64; CACHED_FORMATTED_NUMBERx, CACHED_LOOKUP_URIx, CACHED_MATCHED_NUMBERx, CACHED_NAMEx, CACHED_NORMALIZED_NUMBERx, CACHED_NUMBER_LABELx, CACHED_NUMBER_TYPEx, CACHED_PHOTO_IDx, CONTENT_ITEM_TYPEx, CONTENT_TYPEx, COUNTRY_ISOx, DATA_USAGEx, DATEx, DEFAULT_SORT_ORDERx, DURATIONx, EXTRA_CALL_TYPE_FILTERx, FEATURESx, IS_READx, LIMIT_PARAM_KEYx, NEWx, NUMBERx, NUMBER_PRESENTATIONx, OFFSET_PARAM_KEYx, PHONE_ACCOUNT_COMPONENT_NAMEx, PHONE_ACCOUNT_IDx, TRANSCRIPTIONx, TYPEXx, VOICEMAIL_URIx : string; CallTime: TDateTime; Result: String; begin uri:=StrToJURI('content://call_log/calls'); cursor := SharedActivity.getContentResolver.query(uri, nil, nil,nil,nil); // CACHED_FORMATTED_NUMBER:=cursor.getColumnIndex(StringToJstring('CACHED_FORMATTED_NUMBER')); // CACHED_LOOKUP_URI:=cursor.getColumnIndex(StringToJstring('CACHED_LOOKUP_URI')); // CACHED_MATCHED_NUMBER:=cursor.getColumnIndex(StringToJstring('CACHED_MATCHED_NUMBER')); CACHED_NAME:=cursor.getColumnIndex( TJCallLog_Calls.JavaClass.CACHED_NAME ); // CACHED_NORMALIZED_NUMBER:=cursor.getColumnIndex(StringToJstring('CACHED_NORMALIZED_NUMBER')); // CACHED_NUMBER_LABEL:=cursor.getColumnIndex(StringToJstring('CACHED_NUMBER_LABEL')); // CACHED_NUMBER_TYPE:=cursor.getColumnIndex(StringToJstring('CACHED_NUMBER_TYPE')); // CACHED_PHOTO_ID:=cursor.getColumnIndex(StringToJstring('CACHED_PHOTO_ID')); // CONTENT_ITEM_TYPE:=cursor.getColumnIndex(StringToJstring('CONTENT_ITEM_TYPE')); // CONTENT_TYPE:=cursor.getColumnIndex(StringToJstring('CONTENT_TYPE')); // COUNTRY_ISO:=cursor.getColumnIndex(StringToJstring('COUNTRY_ISO')); // DATA_USAGE:=cursor.getColumnIndex(StringToJstring('DATA_USAGE')); DATE:=cursor.getColumnIndex( TJCallLog_Calls.JavaClass.DATE ); // DEFAULT_SORT_ORDER:=cursor.getColumnIndex(StringToJstring('DEFAULT_SORT_ORDER')); DURATION:=cursor.getColumnIndex( TJCallLog_Calls.JavaClass.DURATION ); // EXTRA_CALL_TYPE_FILTER:=cursor.getColumnIndex(StringToJstring('EXTRA_CALL_TYPE_FILTER')); // FEATURES:=cursor.getColumnIndex(StringToJstring('FEATURES')); // IS_READ:=cursor.getColumnIndex(StringToJstring('IS_READ')); // LIMIT_PARAM_KEY:=cursor.getColumnIndex(StringToJstring('LIMIT_PARAM_KEY')); // NEW:=cursor.getColumnIndex(StringToJstring('NEW')); // NUMBER:=cursor.getColumnIndex(StringToJstring('NUMBER')); // NUMBER_PRESENTATION:=cursor.getColumnIndex(StringToJstring('NUMBER_PRESENTATION')); // OFFSET_PARAM_KEY:=cursor.getColumnIndex(StringToJstring('OFFSET_PARAM_KEY')); // PHONE_ACCOUNT_COMPONENT_NAME:=cursor.getColumnIndex(StringToJstring('PHONE_ACCOUNT_COMPONENT_NAME')); // PHONE_ACCOUNT_ID:=cursor.getColumnIndex(StringToJstring('PHONE_ACCOUNT_ID')); // NUMBER_PRESENTATION:=cursor.getColumnIndex(StringToJstring('NUMBER_PRESENTATION')); // TRANSCRIPTION:=cursor.getColumnIndex(StringToJstring('TRANSCRIPTION')); // TYPEX:=cursor.getColumnIndex(StringToJstring('TYPE')); while (cursor.moveToNext) do begin // CACHED_FORMATTED_NUMBERx:=JStringToString(cursor.getString(CACHED_FORMATTED_NUMBER)); // CACHED_LOOKUP_URIx:=JStringToString(cursor.getString(CACHED_LOOKUP_URI)); // CACHED_MATCHED_NUMBERx:=JStringToString(cursor.getString(CACHED_MATCHED_NUMBER)); CACHED_NAMEx:=JStringToString(cursor.getString(CACHED_NAME)); // CACHED_NORMALIZED_NUMBERx:=JStringToString(cursor.getString(CACHED_NORMALIZED_NUMBER)); // CACHED_NUMBER_LABELx:=JStringToString(cursor.getString(CACHED_NUMBER_LABEL)); // CACHED_NUMBER_TYPEx:=JStringToString(cursor.getString(CACHED_NUMBER_TYPE)); // CACHED_PHOTO_IDx:=JStringToString(cursor.getString(CACHED_PHOTO_ID)); // CONTENT_ITEM_TYPEx:=JStringToString(cursor.getString(CONTENT_ITEM_TYPE)); // CONTENT_TYPEx:=JStringToString(cursor.getString(CONTENT_TYPE)); // COUNTRY_ISOx:=JStringToString(cursor.getString(COUNTRY_ISO)); // DATA_USAGEx:=JStringToString(cursor.getString(DATA_USAGE)); DATEx:=JStringToString(cursor.getString(DATE)); // DEFAULT_SORT_ORDERx:=JStringToString(cursor.getString(DEFAULT_SORT_ORDER)); DURATIONx:=JStringToString(cursor.getString(DURATION)); // EXTRA_CALL_TYPE_FILTERx:=JStringToString(cursor.getString(EXTRA_CALL_TYPE_FILTER)); // FEATURESx:=JStringToString(cursor.getString(FEATURES)); // IS_READx:=JStringToString(cursor.getString(IS_READ)); // LIMIT_PARAM_KEYx:=JStringToString(cursor.getString(LIMIT_PARAM_KEY)); // NEWx:=JStringToString(cursor.getString(NEW)); // NUMBERx:=JStringToString(cursor.getString(NUMBER)); // NUMBER_PRESENTATIONx:=JStringToString(cursor.getString(NUMBER_PRESENTATION)); // OFFSET_PARAM_KEYx:=JStringToString(cursor.getString(OFFSET_PARAM_KEY)); // PHONE_ACCOUNT_COMPONENT_NAMEx:=JStringToString(cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME)); // PHONE_ACCOUNT_IDx:=JStringToString(cursor.getString(PHONE_ACCOUNT_ID)); // NUMBER_PRESENTATIONx:=JStringToString(cursor.getString(NUMBER_PRESENTATION)); // TRANSCRIPTIONx:=JStringToString(cursor.getString(TRANSCRIPTION)); // TYPEXx:=JStringToString(cursor.getString(TYPEX)); CallTime := StrToDateTime(DATEx); <- THIS DON'T WORK! Result := CACHED_NAMEx + ' ' + FormatDateTime('dd.mm.yyyy hh:mm:ss', CallTime) + ' ' + DURATIONx; ShowMessage(Result); end;
  7. Anders Melander

    Threading question

    No disrespect but the same is true of many of those that have below average expertise - The Dunning–Kruger effect. I disagree but it doesn't really matter; The principles are the same regardless of the platform. Under any circumstances, at this point, your (and our) time would be better spent if you tried to locate the source of the problem instead of having everybody guess. Don't blame Windows for that. If you don't understand it then maybe leave threading to those that do. As far as I can see the majority of this thread is people restarting discussion about issues that have already been covered, people suggestion things to try and you trying it with no idea if or why it might or might not work.
  8. Remy Lebeau

    Threading question

    The correct way to use UniqueString() in this example would be like this: procedure StatusOut(const stat: string); var AMsg: string; begin AMsg := stat; UniqueString(AMsg); // use AMsg as needed... end;
  9. David Heffernan

    Threading question

    You clearly don't have a robust understanding of how threads work. The outer caller of SendMessage blocks until that call returns.
  10. Probably that doesn't help you much right now, but I usually decompose more complex views into smaller modules, already before putting all components on one form. To have a few separate views, which show specific aspects of a whole view, like media.play.controller; media.play.playlist, media.play.viewer, all were placed into separate, selfcontaining frames or forms. In my final views I can simple compose them, and connect them via interface bindings and/or messages. Thats way makes it easier to test, compose, re-use and re-place separate parts of a projects view. All it needs is a little more discipline before clicking such complex views or datamodules together, and a little more efford, but I'm not ready either to do this always right, especially when I needed a "fast" solution again
  11. Rollo62

    The interfaces in Delphi are bad?

    @Dalija Prasnikar Yes, I think compiler/linker could get a little smarter though, maybe in the direction like FixInsight or PascalAnalyser can do. To find common anti-patterns, and give warnings, that should be not so far out of reach. But you're right, maybe this is a task for some separate tool probably.
  12. I usually write class helper for this. They can easily be removed when older versions are dropped.
  13. Dalija Prasnikar

    The interfaces in Delphi are bad?

    Yes, interfaces in Delphi are troublesome. From perspective of being tool for achieving abstractions they are commonly more trouble then they are worth. Chad explains some issues well. If they are used as COM interoperability, then there is nothing wrong with the because that was exactly their original purpose. If you are looking on them as tool that can give you automatic memory management they are great, because you can more easily solve some otherwise complex problems that would require complex solutions. However, their use in such cases is limited and you cannot use them for such purpose everywhere. For instance you cannot add ARC to visual frameworks that are build on top of TComponent ownership model and automatically handle lifetime of your visual controls. Main problem with interfaces is not that they are badly done per-se, but that they add duality to Delphi memory management and as such additional complexity and care is needed when you are using them. That is one of the reasons why I liked mobile ARC compiler. It showed that without that duality interfaces and objects can live happily ever after and that you don't have to look around your shoulder every time you use interfaces, expecting that they will kick you in behind. Of course, full ARC brought other issues, but those were related to using existing frameworks that were not written with ARC in mind, so we got that dreadful DisposeOf... No matter how you look at it, Delphi memory management is complex, sometimes too much... it is not question of being able to learn about things, but about how easy and how fast can you write your code, focusing on task at hand without needing to fiddle with all nuisances of handling your objects lifetime.
  14. This is more an FYI, instead of hardcasting a Pointer, you could use Variant Parts in Records to get the illusion of typesafety.
×