Suggested base class additions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Suggested base class additions

James Foster-3
If these overlap any base class methods, my suggestion changes to warn if a
loading package replaces an existing method!

James Foster

--Dolphin--

Collection>>any
 ^self
  detect: [:each | true]
  ifNone: [nil]


File>>workingDirectory: aString
 KernelLibrary default setCurrentDirectory: aString

KernelLibrary>>getProfileString: appName keyName: keyName default:
defaultStr returnedString: retStr size: anInt
    <stdcall: dword GetProfileStringA lpvoid lpvoid lpvoid lpvoid dword >
    self invalidCall

KernelLibrary>>getTickCount
 <stdcall: dword GetTickCount>
 ^self invalidCall

KernelLibrary>>secondsSinceSystemStartup
 ^self getTickCount // 1000

KernelLibrary>>setCurrentDirectory: aStringDirectoryName
 <stdcall: bool SetCurrentDirectoryA lpstr>
 ^self invalidCall

SessionManager>>imageDirectory
 ^File splitPathFrom: self imagePath

UserLibrary>>exitWindowsEx: anInteger
 | answer |
 answer := self exitWindowsEx: anInteger _: 0.
 answer ifTrue: [^self].
 answer := KernelLibrary default getLastError.
 answer = 1314 ifTrue: [self error: 'A required privilege is not held by the
client.'].
 self error: 'Error #' , answer printString

UserLibrary>>exitWindowsEx: uFlags _: dwReason
 <stdcall: bool ExitWindowsEx dword sdword>
 ^self invalidCall

UserLibrary>>forceSystemLogoff
 ^self exitWindowsEx: 0 + 4 "EWX_LOGOFF + EWX_FORCE"

UserLibrary>>forceSystemReboot
 ^self exitWindowsEx: 2 + 4 "EWX_REBOOT + EWX_FORCE"

UserLibrary>>getIdleSeconds
" (Delay forSeconds: 5) wait. UserLibrary default getIdleSeconds "
 | lastEvent current wrap |
 lastEvent := self getLastInputInfo.
 current := Time millisecondClockValue.
 lastEvent <= current ifTrue: [^current - lastEvent // 1000].
 wrap := 2 raisedTo: 32.
 ^current + wrap - lastEvent // 1000 \\ wrap

UserLibrary>>getLastInputInfo
 | buffer flag |
 buffer := ByteArray new: 8.
 buffer
  dwordAtOffset: 0
  put: buffer size.
 flag := self getLastInputInfo: buffer.
 flag ifFalse: [self error: 'Unable to get last input time'].
 ^buffer dwordAtOffset: 4

UserLibrary>>getLastInputInfo: anExternalBuffer
" BOOL GetLastInputInfo(
  PLASTINPUTINFO plii <>   // last input event
 );"
 <stdcall: bool GetLastInputInfo lpvoid>
 ^self invalidCall


--Dolphin MVP Base--

ComandQuery>.command: aSymbol enable: aBoolean
 self command = aSymbol ifTrue: [self isEnabled: aBoolean]

FileSaveDialog>>overwritePrompt
    self style: self style | OFN_OVERWRITEPROMPT

KeyEvent>>upshift
 | char |
 char := Character value: wParam.
 char isLowerCase ifTrue: [wParam := char asUppercase codePoint]

Shell>>upshiftKeyEvent: anEvent
"in #createSchematicWiring can do
    aPresenter when: #keyTyped: send: #upshiftKeyEvent: to: self"
 anEvent upshift

NumberPresenter>>onTextOverflow
 ^self view onTextOverflow

PRINTDLG>>deviceNameFromDevMode
 ^self devModeDo: [:devMode | devMode deviceName]

PRINTDLG>>deviceNameFromDevNames
 ^self devNamesDo: [:devMode | devMode deviceName]

PRINTDLG>>devModeDo: aBlock
 | hDevMode pDevMode devMode answer |
 hDevMode := self hDevMode.
 (pDevMode := KernelLibrary default globalLock: hDevMode) isNil ifTrue:
[^nil].
 [
  devMode := DEVMODE fromAddress: pDevMode.
  answer := aBlock value: devMode.
 ] ensure: [
  KernelLibrary default globalUnlock: hDevMode.
 ].
 ^answer

PRINTDLG>>devNamesDo: aBlock
 | hDevNames pDevNames devNames answer |
 hDevNames := self hDevNames.
 (pDevNames := KernelLibrary default globalLock: hDevNames) isNil ifTrue:
[^self].
 [
  devNames := DEVNAMES fromAddress: pDevNames.
  answer := aBlock value: devNames.
 ] ensure: [
  KernelLibrary default globalUnlock: hDevNames.
 ].
 ^answer

PRINTDLG>>driverName
 ^self devNamesDo: [:devMode | devMode driverName]

PRINTDLG>>outputName
 ^self devNamesDo: [:devNames | devNames outputName]

PrinterCanvas class>>forPrinterNamed: aString
 | hDC |
 hDC := GDILibrary default
  createDC: nil
  lpszDevice: aString asParameter
  lpszOutput: nil
  lpdvminit: nil.
 hDC isNil ifTrue: [^nil].
 ^self withOwnedDC: hDC asInteger

ShellView>>maximize
 self showWithStyle: SW_MAXIMIZE


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Blair McGlashan-3
"James Foster" <[hidden email]> wrote in message
news:43853846$[hidden email]...
> If these overlap any base class methods, my suggestion changes to warn if
> a loading package replaces an existing method!
>
> James Foster
>
> --Dolphin--
> [snip]

James, thanks for your suggestion but we don't normally include new methods
in the base without at least some justification. Sometimes the justification
is obvious, but we'd really have to consider each individually. For example
I'm not sure that including methods to shutdown/reboot is really necessary
for the majority of applications so this probably ought to be an extension
package.

Also some of your suggestions have analagous implementations in the image.
For example the GetTickCount() API is effectively the same as Delay
class>>millisecondClockValue. Collection>>any exists as Collection>>anyOne.
SessionManager>>imageDirectory is equivalent to SessionManager>>imageBase.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

James Foster-3
Blair,
Thanks for your response. I've started a couple new threads with more
detailed justifications for individual methods that I hope you will
reconsider. Here I would like to respond to your more general objection.
While I certainly understand that you would need to consider each addition
individually, I don't agree that the criteria for inclusion should be that
it is "really necessary for the majority of applications" that would be
written in Dolphin. I suppose I'm fighting a "straw man" here, but these
were your words. (If the disagreement is which package should include the
method, then I've misunderstood your objection. My suggestion is for
inclusion in the base image without as much concern about the exact
package.)
First, I think that generally complete coverage of a DLL's API is
worthwhile. The Dolphin tools (particularly the new enhancements with X6)
are so nice for browsing code; I'd much rather look through the methods in
UserLibrary than open up VisualStudio.NET and search the MSDN library (and
I'd rather that developers get in the habit of going first to Dolphin rather
than to VisualStudio.NET when they want to research Windows APIs).
Second, while access to the ExitWindowsEx() method is probably not really
necessary for the majority of applications, I respectfully suggest that it
is not that foreign. One of the commercial applications I've developed with
Dolphin is for a point-of-sale terminal. It is installed in a number of
locations (typically gas station mini-marts) where the clerk is presented
with a simple user interface and effort is made to prevent the user from
having access to the operating system. Windows is used primarily because it
is the host for Dolphin! Other than that, we want to have the Dolphin
application start automatically, and quitting the application should turn
off the machine. I'll grant that this isn't necessary for a majority of
applications, but then I'd bet that ODBC, XML, LargeNegativeIntegers, and a
host of other things aren't "really necessary" either. While I can
realtively easily create my own wrappers for the native API, this is
something that not all developers would be as comfortable doing.
My philosophy on wrapping DLLs is that the Smalltalk goal should be to
"model" the real world. If Microsoft decided to include this API, then the
only reason not to include it is because of the time it takes to manually
generate each of the methods. If someone wants to provide more coverage, it
seems to me that it ought to be available to the community. I'd rather not
have to re-implement something that someone else has already done.
Thanks for a great product.
James Foster

"Blair McGlashan" <[hidden email]> wrote in message
news:[hidden email]...

> "James Foster" <[hidden email]> wrote in message
> news:43853846$[hidden email]...
>> If these overlap any base class methods, my suggestion changes to warn if
>> a loading package replaces an existing method!
>>
>> James Foster
>>
>> --Dolphin--
>> [snip]
>
> James, thanks for your suggestion but we don't normally include new
> methods in the base without at least some justification. Sometimes the
> justification is obvious, but we'd really have to consider each
> individually. For example I'm not sure that including methods to
> shutdown/reboot is really necessary for the majority of applications so
> this probably ought to be an extension package.
>
> Also some of your suggestions have analagous implementations in the image.
> For example the GetTickCount() API is effectively the same as Delay
> class>>millisecondClockValue. Collection>>any exists as
> Collection>>anyOne. SessionManager>>imageDirectory is equivalent to
> SessionManager>>imageBase.
>
> Regards
>
> Blair
>


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Schwab,Wilhelm K
James,

> First, I think that generally complete coverage of a DLL's API is
> worthwhile. The Dolphin tools (particularly the new enhancements with X6)
> are so nice for browsing code; I'd much rather look through the methods in
> UserLibrary than open up VisualStudio.NET and search the MSDN library (and
> I'd rather that developers get in the habit of going first to Dolphin rather
> than to VisualStudio.NET when they want to research Windows APIs).

Even with my level of belief in Smalltalk, I am convinced that is simply
never going to happen.  I recently read a sig with a quote along the
lines of "don't worry about people stealing your ideas, if they are
good, you will need to ram them down their throats".  Sad, but too often
true.


> Second, while access to the ExitWindowsEx() method is probably not really
> necessary for the majority of applications, I respectfully suggest that it
> is not that foreign. One of the commercial applications I've developed with
> Dolphin is for a point-of-sale terminal. It is installed in a number of
> locations (typically gas station mini-marts) where the clerk is presented
> with a simple user interface and effort is made to prevent the user from
> having access to the operating system. Windows is used primarily because it
> is the host for Dolphin!

Likewise, that is about the only reason I still run Windows.  I have
moved to MySQL and Apache for their respective capabilities, and have
not run MS Office in a very long time.


 > Other than that, we want to have the Dolphin
> application start automatically, and quitting the application should turn
> off the machine.

Have you reached that level of control?  Is your app running as the
Windows shell?  Are you willing and able to share code toward that goal?
  Given the security updates have been known to undo changes intended to
idiot proof machines, I am making it a priority to give the default
shell the boot.

I also want to have password protected access to the control panel and
other features of the Windows shell.


 > I'll grant that this isn't necessary for a majority of
> applications, but then I'd bet that ODBC, XML, LargeNegativeIntegers, and a
> host of other things aren't "really necessary" either.

LargeNegativeIntegers might not belong on that list.  One of the
strengths of Smalltalk is that it does the right thing, which might mean
switching to larger number formats.



 > While I can
> realtively easily create my own wrappers for the native API, this is
> something that not all developers would be as comfortable doing.

Realistically, OA's market is not all developers.  Someone needing the
level of control you describe and willing and able to guide Smalltalk in
that direction will get comfortable doing such things.



> My philosophy on wrapping DLLs is that the Smalltalk goal should be to
> "model" the real world. If Microsoft decided to include this API, then the
> only reason not to include it is because of the time it takes to manually
> generate each of the methods. If someone wants to provide more coverage, it
> seems to me that it ought to be available to the community. I'd rather not
> have to re-implement something that someone else has already done.

I think you will find that you often do not need to reimplement such
things.  The last input problem is one that I solved a long time ago,
and would very likely have been able to share with you [*].  Understand
that I take no offense, but if you reinvent the wheel in a vacuum, well,
don't be surprised if it sucks a little :)

With that said, something along the lines of Squeak Map might help us.


[*] Some things that I have done are heavily integrated with stuff that
I cannot distribute for IP reasons.  Most things are not in my goodies
simply because I have not had the time to isolate them, or simply did
not think anyone would care to use them.

Have a good one,

Bill


--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

James Foster-3
Bill,

"Bill Schwab" <[hidden email]> wrote in message
news:CWohf.5125$[hidden email]...

>
> > Other than that, we want to have the Dolphin
>> application start automatically, and quitting the application should turn
>> off the machine.
>
> Have you reached that level of control?  Is your app running as the
> Windows shell?  Are you willing and able to share code toward that goal?
> Given the security updates have been known to undo changes intended to
> idiot proof machines, I am making it a priority to give the default shell
> the boot.
>
I haven't reached that level of control. I don't prevent much in the way of
hacking.

James


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Schwab,Wilhelm K
James,

>>>Other than that, we want to have the Dolphin
>>>application start automatically, and quitting the application should turn
>>>off the machine.
>>
>>Have you reached that level of control?  Is your app running as the
>>Windows shell?  Are you willing and able to share code toward that goal?
>>Given the security updates have been known to undo changes intended to
>>idiot proof machines, I am making it a priority to give the default shell
>>the boot.
>>
>
> I haven't reached that level of control. I don't prevent much in the way of
> hacking.

So you are not running as the shell?  Have you looked at LiteStep?  I
think one can replace the shell with any exe (vaguely recall that from
the 3.x days anyway) and have seen various instructions for making LS
run as the shell, including a manual (regedit) method that I _think_
would work for other software.  Fair warning: I have not yet figured out
whether there are any special command line arguments, or worse, exports
required of a shell under win32.  Why not just use LS?  It does too good
a job of exposing the shell features =:0

Basically, I want to make a Dolphin based shell that runs my cash cow,
FireFox as an impersonated "untrusted" user, and not much else w/o
passwords.  The idea being that I want to be able to walk up to a
machine in use and do just about anything while giving the users very
few options.

It is somewhat on hold right now because the impersonation is partially
hobbled on 2k [*], and I have a pile of changes that I need to square
with my unit tests (still not completely sure which to trust in various
cases - the test or the code).  As that settles, I will be in a better
position.  And yes, this is in large part what Chris has been helping me
sort out, not the code vs. test conflicts, but the preferred shape of of
the objects involved in the worst of the cases.

[*] I agree with its rules for trying to move to a more capable user,
but it's slightly ridiculous to require system privileges to run
something as a guest.  I've read that XP makes it easier, but the
machines for which this is needed are (for now) just flatly stuck on 2k,
which I generally like except for the impersonation hassles.  There is a
service that can hide the details on 2k, but it adds a target for
hackers.  I think they are trying to prevent malware from doing brute
force attacks, but have doubts about their mechanism.  They changed it
so, I guess they did too.

Have a good one,

Bill


--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Sean M-7
In reply to this post by James Foster-3
> I'd much rather look through the methods in UserLibrary than open up
> VisualStudio.NET and search the MSDN library (and I'd rather that
> developers get in the habit of going first to Dolphin rather than to
> VisualStudio.NET when they want to research Windows APIs).

I've never used Visual Studio to look at APIs. I use the trusty Win32.hlp
file.

http://www.arcturus.com.au/win32.zip


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Joseph Frippiat-2
In reply to this post by James Foster-3
"James Foster" <[hidden email]> wrote in message
news:43853846$[hidden email]...
[..]
> ComandQuery>.command: aSymbol enable: aBoolean
> self command = aSymbol ifTrue: [self isEnabled: aBoolean]

Could you confirm that it should be : CommandQuery>>command: aSymbol enable:
aBoolean

[..]

> PRINTDLG>>devModeDo: aBlock
> | hDevMode pDevMode devMode answer |
> hDevMode := self hDevMode.
> (pDevMode := KernelLibrary default globalLock: hDevMode) isNil ifTrue:
> [^nil].
> [
>  devMode := DEVMODE fromAddress: pDevMode.
>  answer := aBlock value: devMode.
> ] ensure: [
>  KernelLibrary default globalUnlock: hDevMode.
> ].
> ^answer

I get this message when I try to add this method :
    Warning message sent to self is not implemented in the receiver's class:
#hDevMode .

Where is the PRINTDLG>>hDevMode ?

Joseph


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Ian Bartholomew-21
Joseph,

> Where is the PRINTDLG>>hDevMode ?

It's a dynamic method that is automatically created when needed.  Have a
look at "Dynamic Field Access" in Dolphin help.

--
Ian

Use the Reply-To address to contact me.
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: Suggested base class additions

Chris Uppal-3
In reply to this post by James Foster-3
James Foster wrote:

> Windows is used
> primarily because it is the host for Dolphin!

That, I think, expresses as well as anything could the argument /against/
trying to achieve complete coverage of the Win32 APIs in the standard image.

If you think of Dolphin as primarily a Smalltalk-flavoured front-end to Win32,
then it'd seem quite natural to have all the API wrapped/exposed.

If, OTOH, you think of Dolphin as a Smalltalk environment that happens to run
on Windows, then the less you see of the Win32 cesspit the better.

Both viewpoints are valid, but I lean to the latter view myself -- I sometimes
have to work at the Win32 level, but I don't like it.  Broadly speaking the
workflow is: (1) decide I want to do something, (2) realise that nothing in the
base image provides that functionality, (3) check the usual goodies and with
luck find something pre-packed by some kind soul, or if not then (4) sigh, (5)
consider carefully whether I really need the function, (6) sigh again, (7) open
up MSDN and start studying the relevant API, (8) give up in disgust, (9) repeat
steps 6..8 an arbitrary number of times, (10) sigh for about the millionth
time, (11) start coding, (12) continue coding, (13) try it and find that it
doesn't work, (14) consider carefully whether suicide might not be an easier
option, (15) go back to MSDN and find (with luck) the cunningly hidden sentence
that points out that the obvious way of using the API doesn't work, (16)
redesign my stuff, (16) more coding, (17) finally it works... on WinXP.  Try it
out on a Win2K machine, goto (5).

The point I'm trying to make is that just having the raw API exposed
(especially if without comments as in your earlier post) doesn't help much.
You /have/ to work from MSDN, and by far the least difficult thing about using
a Win32 feature is actually wrapping any missing structures and APIs.

BTW, if you want to see a Smalltalk that aims primarily to be a front-end for
Win32, then you could check out ST-MT which -- when I last looked (several
years ago) -- tended to use the Win32 APIs raw.

    -- chris