• Using Prf* routines in window procs

    From Vitus Jensen@2:2474/424.1 to all on Mon May 29 17:04:26 2000
    Hej!

    Does anybody know whether Prf* routines are usable from inside a window proc? Do they block or violate the 1/10s rule in any other way?

    Currently I'm using my own Profile routines which are working on memory structures and dump the new contents to disk whenever WM_SAVEAPPLICATION is called. If PrfReadProfileData / PrfWriteProfileData routines use the same scheme (i.e no file access) it would double the memory requirements without need.

    Bye,
    Vitus

    --- Sqed/rexx 570:
    * Origin: A seminar on Time Travel will be held two weeks ago. (2:2474/424.1)
  • From Herbert Rosenau@2:2476/493 to Vitus Jensen on Sat Jun 3 15:53:45 2000
    Am 30.05.00 00:04 schrieb Vitus Jensen

    Hej!

    Does anybody know whether Prf* routines are usable from inside a
    window proc? Do they block or violate the 1/10s rule in any other
    way?

    Use them when you need them!

    Currently I'm using my own Profile routines which are working on
    memory structures and dump the new contents to disk whenever WM_SAVEAPPLICATION is called. If PrfReadProfileData /
    PrfWriteProfileData routines use the same scheme (i.e no file
    access) it would double the memory requirements without need.

    All Prf functions have ony one thing to do: read/write to given profile file.

    General hints:

    1. create you windows hidden!
    Means Let the frame window miss! the WS_VISIBLE
    But let all its childs have the WS_VISIBLE set!
    2. fill in all data you have to fill
    3. if all is done change the visible state!

    During process:

    Whenever you have al lot of work on your vsible window do the steps
    1. WinSetWindowUpdate(hwnd, FALSE)
    2. upate all of them - there is absolutly nothing drawn yet! (saves a lot of time)
    3. if all work done: WinSetWindowUpdate(hwnd, TRUE)
    does the real drawing - once one!
    OWNERDRAWing is done now!

    Another trick for LISTBOX, COMBOBOX, CONTAINER:
    Use always the style OWNERDRAW - and insert ONLY a (shorthand to text converted) Pointer to the real data you would draw. This would save a lot of memory inside PM - Nobody says that you have to fill the items with all real data you have to show! But only GPI has to draw them right. And for that you need a pointer or index inside the item that says YOU what data is to display. Draw it by yourself. You can't insert any binary data into your Items - for that you must convert them to anything that looks like text.

    One of the tuning effects in sqed 2.0:

    1. save a lot of memory by holding only a minimum bytes inside the listbox
    and not all data needed to draw
    2. save a lot of time in
    - copying only a minimum bytes into listbox
    - compare indirectly - and not the whole data


    /* Fuction P2X */ /* */ /* Convert a (previous to string converted) pointer back to its binary */ /* representation. See P2X() for details. */ /* */ /* Parameter: */ /* */ /* PCHAR p pointer to external representation */ /* to a pointer. */ /* */ /* Return: */ /* */ /* PVOID the binary pointer */ /* */ /* */

    PVOID X2P(PCHAR p) {
    ULONG u = 0;
    ULONG i;

    for (i = 0; i < (2 * sizeof(PVOID)); i++) {
    u <<= 4; /* make room for next digit */
    u |= (*p++ & 0x0f); /* only the lower digit of that byte */
    } /* endfor */
    return (PVOID) u; /* return as pointer to void */
    }

    /* Fuction P2X */ /* */ /* Convert a pointer to external format. */ /* This isn't a real hex but seems so. This function is needed to convert */ /* the binary pointer into a printable format. Because a PM control */ /* (e.g. listbox) can't handle binary data and we will use often a simple */ /* pointer to a data struct instead of real data - and then in ownerdraw */ /* display the real data. */ /* */ /* This is done to save a lot of memory. */ /* */ /* Parameter: */ /* */ /* PVOID a the pointer to convert */ /* PCHAR p points to a buffer of 9 bytes. */ /* It's on caller to hold that buffer */ /* in size of 9 bytes or bigger. */ /* */ /* Return: */ /* */ /* PCHAR a pointer to converted string */ /* The lower digits are the info we got */ /* This is identical with p. */ /* We'll return it to become a fuction */ /* ready as parameter for printf(), */ /* strcpy() or so. */ /* */ PCHAR P2X(PVOID a, PCHAR p) {
    PCHAR v = a; /* treate the pointer as pointer to CHAR */
    ULONG i;
    PCHAR p2 = p:

    for (i = 0; i < sizeof(PVOID); i++) {
    *p2++ = (*v >> 4) | 0x30; /* high digit -> ASCII */
    *p2++ = (*v & 0x0f) | 0x30; /* low digit -> ASCII */
    } /* endfor */
    *p2 = '\0';
    return(p);
    }

    /* Fuction AreaFillArea */ /* */ /* Fill an Listbox with all areas */ /* only the pointer to AREA is stored, the draw action has */ /* to draw the real content. */ /* */ /* Parameter: */ /* */ /* HWND hwnd HWND of Window containing the listbox */ /* ULONG id ID of Listbox */ /* */ /* return: - */ /* */ VOID AreaFillArea(HWND hwnd, ULONG id) {
    HWND hwndLB = WinWindowFromID(hwnd, id); /* get the listbox itself */
    PAREA pArea = Areas->pNext;
    CHAR areaName[9];

    WinEnableWindowUpdate(hwnd, FALSE);
    WinSendMsg(hwndLB, LM_DELETEALL, NULL, NULL); /* make the LB empty *T */
    for (; pNext; pNext = pNext->pNext) {
    WinSendMsg(hwndLB, LM_INSERTITEM, (MPARAM) LIT_END,
    (MPARAM) P2X(pNext, areaName));
    } /* endfor */
    WinEnableWindowUpdate(hwnd, TRUE);
    }


    /* Fuction AreaPaintLBItemName */ /* */ /* Paint an item of AREA listbox. The listbox itself contains only a */ /* pointer to the area description. We have to get all info to paint from */ /* the AREA member. Here we paint only the areaname. */ /* */ /* See AreaPaintLBItem() for a more complex painting */ /* */ /* Parameter: */ /* */ /* POWNERITEM poiItem the item to draw */ /* */ /* return: - */ /* */

    VOID AreaPaintLBItemName(POWNERITEM poiItem) {
    COLOR clrForeGround;
    COLOR clrBackGround;
    RECTL rcl;
    CHAR achpArea[9];
    PAREA pArea;

    GpiCreateLogColorTable(poiItem->hps, 0L, LCOLF_RGB, 0L, 0L, (PLONG) NULL);

    clrForeGround = GetPresParam(poiItem->hwnd,
    poiItem->fsState ? PP_HILITEFOREGROUNDCOLOR : PP_FOREGROUNDCOLOR,
    poiItem->fsState ? PP_HILITEFOREGROUNDCOLORINDEX
    : PP_FOREGROUNDCOLORINDEX,
    poiItem->fsState ? SYSCLR_HILITEFOREGROUND : SYSCLR_OUTPUTTEXT);
    clrBackGround = GetPresParam(poiItem->hwnd,
    poiItem->fsState ? PP_HILITEBACKGROUNDCOLOR : PP_BACKGROUNDCOLOR,
    poiItem->fsState ? PP_HILITEBACKGROUNDCOLORINDEX
    : PP_BACKGROUNDCOLORINDEX,
    poiItem->fsState ? SYSCLR_HILITEBACKGROUND : SYSCLR_ENTRYFIELD);

    rcl.xLeft = poiItem->rclItem.xLeft;
    rcl.xRight = poiItem->rclItem.xRight;
    rcl.yTop = poiItem->rclItem.yTop;
    rcl.yBottom = poiItem->rclItem.yBottom;

    /* which area is to draw? */
    WinQueryWindowText(poiItem->hwnd, sizeof(achpArea), achpArea);
    pArea = X2P(achpArea); /* real pointer, please */
    WinDrawText(poiItem->hps, -1l, pArea->pszName, &rcl, clrForeGround,
    clrBackGround, DT_LEFT | DT_VCENTER | DT_ERASERECT);
    poiItem->fsState = poiItem->fsStateOld = FALSE;
    }


    --- Sqed/32 1.15/development 1089:
    * Origin: Gegenden ohne Landschaft nennt man Staedte (2:2476/493)
  • From Coridon Henshaw@1:250/820 to Vitus Jensen on Sat Jun 3 16:15:32 2000
    On Tuesday May 30 2000 at 00:04, Vitus Jensen wrote to all:

    Does anybody know whether Prf* routines are usable from inside a window proc? Do they block or violate the 1/10s rule in any other way?

    I'm using them in a trivial post-it note program without any problems whatsoever. I'm only saving up to 64KiB, though.


    --- GoldED/2 3.0.1
    * Origin: Life sucks and then you croak. (1:250/820)
  • From David Noon@2:257/609.5 to Vitus Jensen on Sun Jun 4 11:14:38 2000
    Hi Vitus,

    Replying to a message of Vitus Jensen to all:

    Does anybody know whether Prf* routines are usable from inside a
    window proc? Do they block or violate the 1/10s rule in any other
    way?

    They block the thread that calls them. The ones that will violate the 1/10 second rule are PrfOpenProfile() and PrfCloseProfile(), as these will always perform physical I/O. The others might or might not perform physical I/O depending on caching of the sectors of the .INI file from previous requests.

    In general, I do my Prf...() calls in a background thread.

    Currently I'm using my own Profile routines which are working on
    memory structures and dump the new contents to disk whenever WM_SAVEAPPLICATION is called. If PrfReadProfileData /
    PrfWriteProfileData routines use the same scheme (i.e no file access)
    it would double the memory requirements without need.

    The Prf...() routines do cache the .INI file quite aggressively, so any application/key/value that has already been read or written will almost certainly be accessed again by cache lookaside. These API's seem to offer quite
    an efficient way to save and restore an application's settings.

    Regards

    Dave
    <Team PL/I>

    --- FleetStreet 1.25.1
    * Origin: The man who broke the bank at Monte Carlo (2:257/609.5)
  • From Herbert Rosenau@2:2476/493 to Vitus Jensen on Thu Jun 8 14:15:33 2000
    Am 08.06.00 00:43 schrieb Vitus Jensen

    But even if the user selected a network drive it would hang the
    PM if the network fails and my program uses PrfWriteProfileData()
    from WM_MOVE.

    OH NO! Post a WM_USER or use WM_SAVEAPPLICATION for that. WM_MOVE is the wrongest place you can find for that.

    --- Sqed/32 1.15/development 373:
    * Origin: Ich Polle, also bin ich (2:2476/493)
  • From Vitus Jensen@2:2474/424.1 to Herbert Rosenau on Fri Jun 9 17:39:28 2000
    Moin Herbert,

    08.06.00 21:15, Herbert Rosenau wrote a message to Vitus Jensen:

    But even if the user selected a network drive it would hang the
    PM if the network fails and my program uses
    PrfWriteProfileData() from WM_MOVE.

    OH NO! Post a WM_USER or use WM_SAVEAPPLICATION for that. WM_MOVE
    is the wrongest place you can find for that.

    See, that's the reply i wanted to hear!

    So the current design will not change: WM_MOVE updates memory structures about the profile contents and WM_SAVEAPPLICATION uses PrfWriteProfileData() to dump the changed entries to disk.

    Bye,
    Vitus

    --- Sqed/rexx 395:
    * Origin: ?OUT OF COFFEE ERROR. (2:2474/424.1)
  • From Vitus Jensen@2:2474/424.1 to Herbert Rosenau on Sun Jun 11 20:11:22 2000
    Moin Herbert,

    10.06.00 19:13, Herbert Rosenau wrote a message to Vitus Jensen:

    So the current design will not change: WM_MOVE updates memory
    structures about the profile contents

    Absolutly needless!

    No (WM_MOVE is an example, take WM_PRESPARAMCHANGED if this suites you better).


    and WM_SAVEAPPLICATION uses PrfWriteProfileData() to dump the
    changed entries to disk.

    WinQueryWindowPos() for frame window size and position does the
    same without having any overhead on management the info. Only size/position of child windows NOT depending on current FRAME
    size are object of separat handling.

    You have to either compare SWPs or set an internal flag on WM_MOVE. So there is overhead, too.


    Presentation params of each window can inspected at any tim with WinQuerypresParams(), ALL window depending information can be
    queried at any time by WinQueryWindowWords(), WinQueryUlong()....
    So you never need to hold lists of them by yourself. Any change
    the user my do is announced before!

    You posted the great idea of subclassing and are now going back to query all and every window? Doing all this querying was my major dislike with presentation parameters and you solved it. I'm not going back.

    The subclassing code updates the in-memory-copy of the profile on any change. On WM_SAVEAPPLICATION the changes are written back (a very simple WM_SAVEAPPLICATION routine).
    And remember your saying about coding same things only once? One function call
    to add PRESPARAM or WM_MOVE handling to a control isn't really bad.




    By that:

    [...i know...]

    Bye,
    Vitus

    --- Sqed/rexx 162:
    * Origin: Age is only important if you're a cheese. (2:2474/424.1)
  • From Herbert Rosenau@2:2476/493 to Vitus Jensen on Mon Jun 12 09:32:42 2000
    Am 12.06.00 03:11 schrieb Vitus Jensen

    So the current design will not change: WM_MOVE updates memory
    structures about the profile contents

    Absolutly needless!

    No (WM_MOVE is an example, take WM_PRESPARAMCHANGED if this
    suites you better).

    Needless too. The PM itself knows all data. You have noways to hold them by yourself - except on startup and shutdown of your application.

    and WM_SAVEAPPLICATION uses PrfWriteProfileData() to dump the
    changed entries to disk.

    WinQueryWindowPos() for frame window size and position does the
    same without having any overhead on management the info. Only
    size/position of child windows NOT depending on current FRAME
    size are object of separat handling.

    You have to either compare SWPs or set an internal flag on
    WM_MOVE. So there is overhead, too.

    If you have to control the size/position you have to compare to a static min/max and update the NEW position/size with that. Both messages gets you the old AND new size (and WM_MOVE: positions) so you don#t need to hold them by yourself. The minimum/maximum framesize you would allow are more or less static
    values. So you can smply compare the NEW (from message) ones with your min/max and change them on the fly.

    Presentation params of each window can inspected at any tim with
    WinQuerypresParams(), ALL window depending information can be
    queried at any time by WinQueryWindowWords(),
    WinQueryUlong().... So you never need to hold lists of them by
    yourself. Any change the user my do is announced before!

    You posted the great idea of subclassing and are now going back
    to query all and every window? Doing all this querying was my
    major dislike with presentation parameters and you solved it.
    I'm not going back.

    Yepp - but there is absolutly no need to hold all of them in own data structures because PM does it for itself - and lets you ask for them if you have to handle them by yourself. Holding them in own data structures costs a lot of memory and TIME.

    The subclassing code updates the in-memory-copy of the profile on
    any change. On WM_SAVEAPPLICATION the changes are written back (a
    very simple WM_SAVEAPPLICATION routine). And remember your saying
    about coding same things only once? One function call to add
    PRESPARAM or WM_MOVE handling to a control isn't really bad.

    In WM_SAVEAPPLICATION you has to ask the PM itself for the current data. You don't need to hold all of them yourself in memory. Any action PM my change them
    by user request you'll informed to get you a chance to modify the user given data before the PM realises the change - for better control your resources. Not
    to give you the possibiltity to hold them by yourself in own data structures and spend useless memory and runtime.

    On startup build your resources (frames _without_ WS_VISIBLE),
    - in WM_CREATE/WM_INITDLG
    - get the current presparams, window positions, size from YOUR profile
    - set them to PM by PrfWrite...() - to os2*.ini
    - then use WinSetWindowPos() to set last saved size and position AND
    to change the state to visible. Now your resources would be displayed
    in correct sise and position with last saved (you'd done even for PM)
    presentation marams.
    - in WM_MOVE/SIZE
    - only if you need to have a minimum/maximum visible window size
    and if you like the user can minimise/maximise the window
    and he is doing so: nothing to do
    if the user is simply sizing the window:
    compare the new size to your min/max, change the actual parameters
    and let PM the sizing done - absolutly nothing for you to hold in
    own memory (except your min/max
    - if the user should never min/max remove simply one/both entries
    from system menue and frame.
    - WM_PRESPARAMSCHANGED
    - control the new presparams if they are useable for YOU
    if NOT change them to anything you like, let PM do the work
    - WM_SAVEAPPLICATION
    - query PM for all data you has to save
    - Window position and size (special point: mini/maximised!)
    - if you'll hold pressentation params in your own profile
    get them with Prf- functions from OS2*.ini and wirte them
    into your own to have them ready on restart.
    - optinally you can ignore the message and do that only in
    - WM_CLOSE
    - - see WM_SAVEAPPLICATION
    - do some cleanup on user data depending on window to close

    A runtime compromise is: holding some FONT data (char width and hight) in private words to have quicker access during draw action if you have to control that yourself - but only if you're uses fixed fonts or you can live the MAX_AVERAGE.

    By holding all presparams and window words by yourself you'll spend more time and memory for that as you ever can save by asking PM for current values if you
    need them.

    You should do:
    - any drawing of bitmaps in an separate thread in one or more
    memory presenation space(s) asyncron
    - in WM_DRAW simply use a bitcopy from one presentation space (last drawn)
    into the one PM holds for drawing
    - fill/delete/search listboxes in other threads
    for mainupate them use WinUpdateWindow(hwnd, FALSE)
    - do the action
    WinUpdateWindow(hwnd, TRUE)


    --- Sqed/32 1.15/development 556:
    * Origin: Lieber eine gute Stellung, als 'ne gute Arbeit! (2:2476/493)
  • From Vitus Jensen@2:2474/424.1 to Coridon Henshaw on Wed Jun 7 17:43:38 2000
    Moin Coridon,

    03.06.00 23:15, Coridon Henshaw wrote a message to Vitus Jensen:

    Does anybody know whether Prf* routines are usable from inside a
    window proc? Do they block or violate the 1/10s rule in any
    other way?

    I'm using them in a trivial post-it note program without any
    problems whatsoever. I'm only saving up to 64KiB, though.

    Are you using the OS2.INI or your own profile?
    All my programs ask the user where to place the profile and as they are seldom used setup/test programs the user might select a floppy drive (starting from floppy is still an option when dealing with 100KB exes).

    But even if the user selected a network drive it would hang the PM if the network fails and my program uses PrfWriteProfileData() from WM_MOVE.

    Bye,
    Vitus

    --- Sqed/rexx 623:
    * Origin: Please insert a new HARD-DISK and press any key (2:2474/424.1)
  • From Vitus Jensen@2:2474/424.1 to David Noon on Wed Jun 7 18:19:39 2000
    Moin David,

    04.06.00 18:14, David Noon wrote a message to Vitus Jensen:

    Does anybody know whether Prf* routines are usable from inside a
    window proc? Do they block or violate the 1/10s rule in any
    other way?

    They block the thread that calls them. The ones that will violate
    the 1/10 second rule are PrfOpenProfile() and PrfCloseProfile(),
    as these will always perform physical I/O. The others might or
    might not perform physical I/O depending on caching of the
    sectors of the .INI file from previous requests.

    In general, I do my Prf...() calls in a background thread.

    Feeding it via a pipe or [message] queue, i assume?


    Currently I'm using my own Profile routines which are working on
    memory structures and dump the new contents to disk whenever
    WM_SAVEAPPLICATION is called. If PrfReadProfileData /
    PrfWriteProfileData routines use the same scheme (i.e no file
    access) it would double the memory requirements without need.

    I should have added that I use PrfWriteProfileData to do this dump in WM_SAVEAPPLICATION.


    The Prf...() routines do cache the .INI file quite aggressively,
    so any application/key/value that has already been read or
    written will almost certainly be accessed again by cache
    lookaside. These API's seem to offer quite an efficient way to
    save and restore an application's settings.

    From the usual discussions about OS2.INI (size and writing strategy) I was under the impression that OS/2 holds the complete file in memory. If this were
    true and PrfOpenProfile is responsible for this caching, PrfWriteProfileData would most certainly *not* block (because it only has to update the inmemory copy).

    What you told me is that
    1. PrfWriteProfileData might block (forcing me to keep my design of buffering) 2. PrfReadProfileData will cause some/most of the contents to remain in memory (cache)

    As my design holds a copy of the profile in memory this will double the memory requirements. Stop. :-(

    Bye,
    Vitus

    --- Sqed/rexx 2:
    * Origin: 2B OR NOT 2B is the question - FF the answer! (2:2474/424.1)
  • From Herbert Rosenau@2:2476/493 to Vitus Jensen on Sat Jun 10 12:13:00 2000
    Am 10.06.00 00:39 schrieb Vitus Jensen

    So the current design will not change: WM_MOVE updates memory
    structures about the profile contents

    Absolutly needless!

    and WM_SAVEAPPLICATION uses PrfWriteProfileData() to dump the
    changed entries to disk.

    WinQueryWindowPos() for frame window size and position does the same without having any overhead on management the info. Only size/position of child windows
    NOT depending on current FRAME size are object of separat handling.

    Presentation params of each window can inspected at any tim with WinQuerypresParams(), ALL window depending information can be queried at any time by WinQueryWindowWords(), WinQueryUlong().... So you never need to hold lists of them by yourself. Any change the user my do is announced before!

    By that:

    In WM_MOVE/WM_SIZE you my modify the size and coordinates of the actual (new size/position in MPARAMS to your need - and then let do PM the annouced (SIZE/MOVE) action.

    WM_MOVE: The point defined by x/y is changed, the point defined by cx/cy my or my not changed.

    WM_SIZE: the point defined by x/y is NOT changed, the point defined by cx/cy is
    object of change.

    You my
    - disallow or restrict the announced action by direct manipulation the new coordinate pairs of the message if you like to do so. Both messages are a announce for the action, so you can manipulate it as you (the programmer) likes
    to do - before the action is really done.

    You should never send one of the messages! Instead use WinSetWindowPosition, because WinSetWindowPosition does the announcements, then invalidates ALL required rectangles and then sends WM_DRAW to all windows for redrawing.

    --- Sqed/32 1.15/development 322:
    * Origin: Es ist nicht alles rund, was Ecken hat ... (2:2476/493)
  • From David Noon@2:257/609.5 to Vitus Jensen on Tue Jun 20 13:21:36 2000
    Hi Vitus,

    Replying to a message of Vitus Jensen to David Noon:

    In general, I do my Prf...() calls in a background thread.

    Feeding it via a pipe or [message] queue, i assume?

    Usually I place a request -- either to read a key/application value into a buffer, or write one from a buffer -- into some memory area shared by the threads and post a semaphore. The write operation is simply "fire-and-forget". The read operation does a WinPostMsg() with WM_USER+??? from the background thread when it is complete. One can invent more exotic schemes to produce time-out errors, by having the forground thread handle WM_TIMER or WM_USER messages accordingly, but this is seldom necessary.

    I should have added that I use PrfWriteProfileData to do this dump in WM_SAVEAPPLICATION.

    Ok.

    The Prf...() routines do cache the .INI file quite aggressively,
    so any application/key/value that has already been read or
    written will almost certainly be accessed again by cache
    lookaside. These API's seem to offer quite an efficient way to
    save and restore an application's settings.

    From the usual discussions about OS2.INI (size and writing strategy) I
    was under the impression that OS/2 holds the complete file in memory.

    This is true about OS2.INI and OS2SYS.INI, but that could just be the WPS reading everything up front. I am not certain about other .INI files. The application/key values are certainly cached once they've been read and/or written, and remain cached until the PrfCloseProfile() call, at least in modest
    sized files.

    If this were true and PrfOpenProfile is responsible for this caching, PrfWriteProfileData would most certainly *not* block (because it only
    has to update the inmemory copy).

    This is largely correct. [You can be blocked if you have a page fault that needs to be resolved from SWAPPER.DAT, but that can happen anywhere.] However, I have done large copies of application/key pairs from one .INI file to another
    and the output file was only accessed when the PrfCloseProfile() call was made;
    none of the PrfWriteProfileData() calls caused the copy utility to block. I cannot be certain that the cache is not limited in size, and once that size is reached the cache is flushed on, say, a least-recently used basis. If Denis Tonn were still reading this echo, he would likely have been able to tell us what limits there are.

    So, if there is a size limit your calls _will_ block once you have cached that much data. If there is no limit they will not block.

    What you told me is that
    1. PrfWriteProfileData might block (forcing me to keep my design of buffering)

    Sometimes it _might_ block, but that is seldom.

    2. PrfReadProfileData will cause some/most of the contents
    to remain in memory (cache)

    Correct, but PrfReadProfileData() can block if the application/key pair has not
    already been accessed.

    As my design holds a copy of the profile in memory this will double
    the memory requirements. Stop. :-(

    Just use the .INI file's cache instead.

    Regards

    Dave
    <Team PL/I>

    --- FleetStreet 1.25.1
    * Origin: The man who broke the bank at Monte Carlo (2:257/609.5)
  • From Coridon Henshaw@1:250/820 to Vitus Jensen on Sun Jun 25 06:38:38 2000
    On Thursday June 08 2028 at 00:43, Vitus Jensen wrote to Coridon Henshaw:

    I'm using them in a trivial post-it note program without any
    problems whatsoever. I'm only saving up to 64KiB, though.

    Are you using the OS2.INI or your own profile?

    I'm saving into OS2.INI from a WM_SAVEAPPLICATION message handler. Writing to user-specified configs isn't something you should be doing from the main thread, particularly if the configs could be on a floppy.

    But even if the user selected a network drive it would hang the PM if
    the network fails and my program uses PrfWriteProfileData() from
    WM_MOVE.

    There's no need to rewrite window position data on every WM_MOVE message. Just
    call WinQueryWindow() from a WM_SAVEAPPLICATION handler and write the window locations when the program exits.


    --- GoldED/2 3.0.1
    * Origin: Life sucks and then you croak. (1:250/820)