/*::.
==================================================================================================================================
=================================================¦ Copyright © 2014 Allen Baker ¦=================================================
+------------------------------+
File: ConsoleInfo.java
Originator: Allen Baker (2014.07.04 20:44)
LayoutRev: 5
================================================================================================================================== */
package cosmicabyss.com.lib;
import java.io.*;
import java.util.*;
import java.net.*;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
/*::
======================================================================================================================== *//**
Instances of this class represent a Windows console window. This class leverages the Java Native Access (JNA) libraries
which are located at: https://github.com/twall/jna.<P>
Salient characteristics of ConsoleInfos are:
<BLOCKQUOTE>
=> It accesses a native Windows library to get the Windows-specific console screen properties.
</BLOCKQUOTE>
<P>
<DL>
<DT>
<B>
Example usage:
</B>
<DD>
<BLOCKQUOTE>
<PRE id="unindent">
=========================================================================================
Get a the properties of the current console window directly from the OS.
-----------------------------------------------------------------------------------------
Kernel32.ConsoleWindowScreenBufferInfo theInfo = info();
System.out.printf("size .x=%d .y=%d\n", theInfo.wSizeX, theInfo.wSizeY);
System.out.printf("cursor .x=%d .y=%d\n", theInfo.wCursorPositionX, theInfo.wCursorPositionY);
System.out.printf("window .left=%d .top=%d .right=%d .bottom=%d\n", theInfo.wWindowLeft, theInfo.wWindowTop, theInfo.wWindowRight, theInfo.wWindowBottom);
System.out.printf("max-window-size .x=%d .y=%d\n", theInfo.wMaximumWindowSizeX, theInfo.wMaximumWindowSizeY);
System.out.println("WIDTH IS " + width());
</PRE>
</BLOCKQUOTE>
</DD>
</DT>
<DT>
<B>
View Source:
</B>
<DD>
<A href="ConsoleInfo.java.html">
ConsoleInfo.java
</A>
</DD>
</DT>
<DT>
<B>
Author:
</B>
<DD>
<A href="mailto:sourcecode.v01@cosmicabyss.com">
Allen Baker
</A>
</DD>
</DT>
</DL>
*//*
======================================================================================================================== */
public class ConsoleInfo
{
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Constants ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*.
==========================================================================================
CLASS_NAME:
The name of this class
DFLT_LINE_LEN:
The default line length for word wrapping
------------------------------------------------------------------------------------------ */
private static final XString CLASS_NAME = new XString(ConsoleInfo.class.getName());
private static final int DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Types ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Enums ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Structs ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Classes ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Interfaces ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
public interface Kernel32 extends StdCallLibrary
{
Kernel32 INSTANCE = (Kernel32)
Native.loadLibrary("kernel32", Kernel32.class);
int STD_INPUT_HANDLE = -10;
int STD_OUTPUT_HANDLE = -11;
int STD_ERROR_HANDLE = -12;
int GetStdHandle(int nStdHandle);
public static class ConsoleWindowScreenBufferInfo extends Structure
{
public short wSizeX; // effective console width
public short wSizeY;
public short wCursorPositionX;
public short wCursorPositionY;
public short wAttributes;
public short wWindowLeft;
public short wWindowTop;
public short wWindowRight;
public short wWindowBottom;
public short wMaximumWindowSizeX;
public short wMaximumWindowSizeY;
}
boolean GetConsoleScreenBufferInfo(int hConsoleOutput, ConsoleWindowScreenBufferInfo lpConsoleScreenBufferInfo);
}
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Variables ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*.
==========================================================================================
cOut:
Formatted and time-stamped console output.
------------------------------------------------------------------------------------------ */
private static ConsoleStream cOut = ConsoleStream.getSingleton();
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Functions ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Constructors ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*: :METHOD:000:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a ConsoleInfo class object.
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#000">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public ConsoleInfo() throws Exception
{
initializeInstanceConstantsAndVariables();
}
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Initialization ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
static
{
/*.
==========================================================================================
Make sure all the class constants and variables are initialized the first time the JVM
loads this class code and before anything else in this class is accessed
------------------------------------------------------------------------------------------ */
initializeClassConstantsAndVariables();
}
/*: :METHOD:001:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method initializes all the class constants and variables
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#001">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
private static void initializeClassConstantsAndVariables()
{
}
/*: :METHOD:002:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method initializes all the instance constants and variables. The intent of this method is to
encapsulate all the common instance initializations in one place that can be called from all the
constructors.
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#002">View source</A>
@return
True if the initialization succeeded, flase otherwise.
*//*
---------------------------------------------------------------------------------------------------- */
private boolean initializeInstanceConstantsAndVariables() throws Exception
{
boolean successCode = true;
if (successCode)
{
}
return successCode;
}
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Methods ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*: :METHOD:003:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method sets the ConsoleStream for this object.
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#003">View source</A>
@return
A reference to this object
@param
pConsole is a ConsoleStream through which this objects sends its output.
*//*
---------------------------------------------------------------------------------------------------- */
public ConsoleInfo setOut(ConsoleStream pConsole)
{
cOut = pConsole;
return this;
}
/*: :METHOD:004:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This boilerplate method is used for testing an instantiated object of this class and may include any
code the developer chooses.
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#004">View source</A>
@return
A reference to this object
*//*
---------------------------------------------------------------------------------------------------- */
public ConsoleInfo test() throws Exception
{
cOut.titledPrintf
(
"\"HELLO WORLD!\"",
"%s %s %s",
"I'm an object of the", CLASS_NAME, "class, and I approved this message."
);
Kernel32.ConsoleWindowScreenBufferInfo theInfo = info();
System.out.printf("size .x=%d .y=%d\n", theInfo.wSizeX, theInfo.wSizeY);
System.out.printf("cursor .x=%d .y=%d\n", theInfo.wCursorPositionX, theInfo.wCursorPositionY);
System.out.printf("window .left=%d .top=%d .right=%d .bottom=%d\n", theInfo.wWindowLeft, theInfo.wWindowTop, theInfo.wWindowRight, theInfo.wWindowBottom);
System.out.printf("max-window-size .x=%d .y=%d\n", theInfo.wMaximumWindowSizeX, theInfo.wMaximumWindowSizeY);
System.out.println("WIDTH IS " + width());
return this;
}
/*: :METHOD:005:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns the ConsoleWindowScreenBufferInfo for the current console window.
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#005">View source</A>
@return
This method returns the ConsoleWindowScreenBufferInfo for the current console window.
*//*
---------------------------------------------------------------------------------------------------- */
public static Kernel32.ConsoleWindowScreenBufferInfo info()
{
Kernel32 lib = Kernel32.INSTANCE;
int h = lib.GetStdHandle(Kernel32.STD_OUTPUT_HANDLE);
Kernel32.ConsoleWindowScreenBufferInfo theInfo = new Kernel32.ConsoleWindowScreenBufferInfo();
lib.GetConsoleScreenBufferInfo(h, theInfo);
return theInfo;
}
/*: :METHOD:006:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns the width in characters for the current console window.
NOTICE! Hard-learned info to follow - I chased my tail for quite a while on it:
The Kernel32 call through GetConsoleScreenBufferInfo() apparently returns 0 for the screen width
whenever stdout is redirected or piped from the commandline. For example, this line which is
paraphrased from the batch file MirrorInternalDrive.bat and redirects stdout to logfile.txt:
<BLOCKQUOTE>
<PRE id="unindent">
call mirror I:\ J:\ >> logfile.txt
</PRE>
</BLOCKQUOTE>
Invokes DirectoryPruner.class. DirectoryPruner.class uses this method to find the
Console window width. Without the redirection, it works fine; with the redirection, this method -
width() - returns 0. Therefor, I inserted code into width() to return 200 instead of
theInfo.wMaximumWindowSizeX if theInfo.wMaximumWindowSizeX is 0.
200 is a total guess at the minimum likely cmd window width.
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#006">View source</A>
@return
This method returns the width in characters for the current console window or 200 if the system
call retuns 0 for a screen window width..
*//*
---------------------------------------------------------------------------------------------------- */
public static int width()
{
int result = 0;
Kernel32.ConsoleWindowScreenBufferInfo theInfo = info();
result = (theInfo.wMaximumWindowSizeX == 0)? 200 : theInfo.wMaximumWindowSizeX;
return result;
}
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Main ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*: :METHOD:007:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method allows this class file to be unit tested as a standalone application. It's the method
that's called when the class is invoked from the command line by using the java application launcher
- "java". Main() is not a required method, but the practice of putting one in each class and
wrapping class test code within it allows easy unit testing of the class; and main does not need to
be removed when testing is complete.
<P>
<DL>
<DT>
<B>
Command line usage:
</B>
<DD>
Java cosmicabyss.com.lib.ConsoleInfo
</DD>
</DT>
</DL>
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#007">View source</A>
@param
pArgs contains the command line arguments with which this class was invoked as an application.
*//*
---------------------------------------------------------------------------------------------------- */
public static void main(String[] pArgs) throws Exception
{
/*.
==========================================================================================
Greetings !
------------------------------------------------------------------------------------------ */
cOut.banner(CLASS_NAME);
/*.
==========================================================================================
Create an object and send its output to the ConsoleStream
------------------------------------------------------------------------------------------ */
ConsoleInfo obj = new ConsoleInfo();
/*.
==========================================================================================
Test code
------------------------------------------------------------------------------------------ */
obj.test();
}
} // End of Class ConsoleInfo
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Notes ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*: :METHOD:008:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method => -> -- c c c c c c c
<P><B>Implementation: </B><A HREF="ConsoleInfo.java.html#008">View source</A>
@return
This method returns
@exception
Xx is thrown when
@exception
Yy is thrown when
@param
PX (optional)(input/output)(output) is the
@param
PY (optional)(input/output)(output) is the
*//*
---------------------------------------------------------------------------------------------------- */
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Section Level 0 Banner ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*:.
==============================================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[ Section Level 1 Banner ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
============================================================================================================== */
/*:.
==============================================================================================================
:::::::::::::::::::::::::::::::::::::::::[ Section Level 2 Banner ]:::::::::::::::::::::::::::::::::::::::::
============================================================================================================== */
/*:.
==============================================================================================================
-----------------------------------------[ Section Level 3 Banner ]-----------------------------------------
============================================================================================================== */
/*:.
==============================================================================================================
[ Section Level 4 Banner ]
============================================================================================================== */
Copyright © 2012 Allen Baker
|