Note: Added a command “DisplayRotate" to AutoHotkey

AutoHotkey is a powerful tools on windows platform. it’s a GPL program. so provide all source code.also when need a display rotate feature. Can to do it by myself.

the place provide a implement methed to add new command "DisplayRotate" in Autohotkey script language.

a test demo script like the below

DisplayRotate 90
Sleep 2000
DisplayRotate 180
Sleep 2000
DisplayRotate 270
Sleep 2000
DisplayRotate 0
Sleep 2000
DisplayRotate
Sleep 2000
DisplayRotate
Sleep 2000
But the funtion just test on WinXP/Intel GMA driver. The feature need Win2K or later OS and VGA driver support.

click here get a package include all source code,

need Build Env. Visual Studio 2005, remember download "UPX" if need build a release version


— C:AutoHotkey104805_sourcesourcedefines.h    Fri Sep 25 06:55:53 2009 UTC
+++ C:AutoHotkey104805_Modifysourcedefines.h    Wed Oct 14 10:00:40 2009 UTC
@@ -176,6 +176,9 @@
#define SYM_DYNAMIC_IS_DOUBLE_DEREF(token) (token.buf) // SYM_DYNAMICs other than doubles have NULL buf, at least at the stage this macro is called.
#define SYM_DYNAMIC_IS_VAR_NORMAL_OR_CLIP(token) (!(token)->buf && ((token)->var->Type() == VAR_NORMAL || (token)->var->Type() == VAR_CLIPBOARD)) // i.e. it’s an evironment variable or the clipboard, not a built-in variable or double-deref.
+// new enum by KunYi
+enum DisplayOrientationType { DO_INVALID = 0, DO_0, DO_90, DO_180, DO_270, DO_TOGGLE};
+
struct DerefType; // Forward declarations for use below.
class Var;        //
struct ExprTokenType  // Something in the compiler hates the name TokenType, so using a different name.
@@ -291,6 +294,8 @@
, ACT_EDIT, ACT_RELOAD, ACT_MENU, ACT_GUI, ACT_GUICONTROL, ACT_GUICONTROLGET
, ACT_EXITAPP
, ACT_SHUTDOWN
+// add new command by KunYi
+, ACT_DISPLAYROTATE
// Make these the last ones before the count so they will be less often processed.  This helps
// performance because this one doesn’t actually have a keyword so will never result
// in a match anyway.  UPDATE: No longer used because Run/RunWait is now required, which greatly

— C:AutoHotkey104805_sourcesourceglobaldata.cpp    Mon Apr 13 09:19:12 2009 UTC
+++ C:AutoHotkey104805_Modifysourceglobaldata.cpp    Wed Oct 14 09:51:53 2009 UTC
@@ -520,6 +520,9 @@
     , {"ExitApp", 0, 1, 1, {1, 0}}  // Optional exit-code. v1.0.48.01: Allow an expression like ACT_EXIT does.
     , {"Shutdown", 1, 1, 1, {1, 0}} // Seems best to make the first param (the flag/code) mandatory.
+   
+    // added the command by KunYi
+    , {"DisplayRotate", 0, 1, 1, NULL } // 0/90/180/270/Toggle/Blank (blank is the same as toggle)
};
// Below is the most maintainable way to determine the actual count?
// Due to C++ lang. restrictions, can’t easily make this a const because constants

— C:AutoHotkey104805_sourcesourcescript.cpp    Fri Sep 25 06:58:31 2009 UTC
+++ C:AutoHotkey104805_Modifysourcescript.cpp    Wed Oct 14 09:49:52 2009 UTC
@@ -1182,7 +1182,9 @@
     // section further below.
     if (fgets(buf, 4, fp)) // Success (the fourth character is the terminator).
     {
–        if (strcmp(buf, "嚜?))  // UTF-8 BOM marker is NOT present.
+        const unsigned char U8_BOM[4] = { 0xef, 0xbb, 0xbf, 0x00};
+
+        if (strcmp(buf, (char*)U8_BOM))  // UTF-8 BOM marker is NOT present.
             rewind(fp);  // Go back to the beginning so that the first three bytes aren’t omitted during loading.
             // The code size of rewind() has been checked and it seems very tiny.
     }
@@ -6390,6 +6392,13 @@
         if (aArgc > 0 && !line.ArgHasDeref(1) && strlen(new_raw_arg1) > 1 && !TextToVK(new_raw_arg1) && !ConvertJoy(new_raw_arg1))
             return ScriptError(ERR_INVALID_KEY_OR_BUTTON, new_raw_arg1);
         break;
+
+    // new command by KunYi
+    case ACT_DISPLAYROTATE:
+        if (aArgc > 0 && !line.ConvertDisplayOrientation(new_raw_arg1))
+            return ScriptError(ERR_PARAM1_INVALID, new_raw_arg1);
+        break;
+
#endif  // The above section is in place only if when not AUTOHOTKEYSC.
     }
@@ -13232,6 +13241,11 @@
     case ACT_SHUTDOWN:
         return Util_Shutdown(ArgToInt(1)) ? OK : FAIL; // Range of ARG1 is not validated in case other values are supported in the future.
+   
+    case ACT_DISPLAYROTATE:
+        Util_DisplayRotate(ConvertDisplayOrientation(ARG1));
+        return OK;
+
     } // switch()
     // Since above didn’t return, this line’s mActionType isn’t handled here,

— C:AutoHotkey104805_sourcesourcescript.h    Mon Sep 21 12:19:59 2009 UTC
+++ C:AutoHotkey104805_Modifysourcescript.h    Wed Oct 14 09:49:48 2009 UTC
@@ -1750,6 +1750,18 @@
         return VAR_TYPE_INVALID;
     }
+
+    static DisplayOrientationType ConvertDisplayOrientation(char* aBuf)
+    {
+        if (!aBuf || !*aBuf) return DO_TOGGLE;
+        if (!stricmp(aBuf, "0")) return DO_0;
+        if (!stricmp(aBuf, "90")) return DO_90;
+        if (!stricmp(aBuf, "180")) return DO_180;
+        if (!stricmp(aBuf, "270")) return DO_270;
+        if (!stricmp(aBuf, "Toggle")) return DO_TOGGLE;
+        return DO_INVALID;
+    }
+
     static ResultType ValidateMouseCoords(char *aX, char *aY)
     {
         // OK: Both are absent, which is the signal to use the current position.
@@ -2727,4 +2739,6 @@
bool ScriptGetKeyState(vk_type aVK, KeyStateTypes aKeyStateType);
double ScriptGetJoyState(JoyControls aJoy, int aJoystickID, ExprTokenType &aToken, bool aUseBoolForUpDown);
+bool Util_DisplayRotate(int DO);
+
#endif

— C:AutoHotkey104805_sourcesourcescript_autoit.cpp    Sun Sep 13 09:13:09 2009 UTC
+++ C:AutoHotkey104805_Modifysourcescript_autoit.cpp    Wed Oct 14 14:38:33 2009 UTC
@@ -2281,3 +2281,129 @@
     FreeLibrary(hinstLib);
     return 0;  // Not found.
}
+
+static void swap(DWORD& v1, DWORD& v2)
+{
+    DWORD t;
+    t = v1;
+    v1 = v2;
+    v2 = t;
+}
+
+bool Util_DisplayRotate(int DO)
+{
+    /* the below ref.
+    *    <a href="http://msdn.microsoft.com/en-us/library/ms812499.aspx">
+    *    Changing Screen Orientation Programmatically</a>
+    */
+    DEVMODEW dm;
+   
+    // initialize the DEVMODE structure
+    ZeroMemory(&dm, sizeof(dm));
+    dm.dmSize = sizeof(dm);
+   
+    typedef BOOL (WINAPI *myEnumDisplaySettings)
+        (/* in */ LPCSTR lpszDeviceName,
+         /* in */ DWORD iModeNum,
+         /* out */ DEVMODEW* lpDevMode);
+    typedef LONG (WINAPI *myChangeDisplaySettings)
+        (/* in */  DEVMODEW *lpDevMode,
+         /* in */ DWORD dwflags);
+
+    static myEnumDisplaySettings lpfnEDS = (myEnumDisplaySettings)GetProcAddress(GetModuleHandle("user32"), "EnumDisplaySettingsW");
+    static myChangeDisplaySettings lpfnCDS = (myChangeDisplaySettings)GetProcAddress(GetModuleHandle("user32"), "ChangeDisplaySettingsW");
+    if (!(lpfnEDS && lpfnCDS))
+        return false; // not support either function, due to need Win2K or later OS
+   
+    if (!lpfnEDS(NULL, ENUM_CURRENT_SETTINGS, &dm))
+        return false;
+
+    switch(DO) {
+    case DO_INVALID:
+        return false;
+    case DO_0:
+        switch (dm.dmDisplayOrientation) {
+        case DMDO_DEFAULT:
+            // nothing
+            return true;
+        case DMDO_90:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        case DMDO_180:
+            break;
+        case DMDO_270:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        }
+        dm.dmDisplayOrientation = DMDO_DEFAULT;
+        break;
+    case DO_90:
+        switch (dm.dmDisplayOrientation) {
+        case DMDO_DEFAULT:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        case DMDO_90:
+            // nothing
+            return true;
+        case DMDO_180:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        case DMDO_270:
+            break;
+        }
+        dm.dmDisplayOrientation = DMDO_90;
+        break;
+    case DO_180:
+        switch (dm.dmDisplayOrientation) {
+        case DMDO_DEFAULT:
+            break;
+        case DMDO_90:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        case DMDO_180:
+            // nothing
+            return true;
+        case DMDO_270:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        }
+        dm.dmDisplayOrientation = DMDO_180;
+        break;
+    case DO_270:   
+        switch (dm.dmDisplayOrientation) {
+        case DMDO_DEFAULT:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        case DMDO_90:
+            break;
+        case DMDO_180:
+            swap(dm.dmPelsHeight, dm.dmPelsWidth);
+            break;
+        case DMDO_270:
+            // nothing
+            return true;
+        }
+        dm.dmDisplayOrientation = DMDO_270;
+        break;
+    case DO_TOGGLE:
+        switch (dm.dmDisplayOrientation) {
+        case DMDO_DEFAULT:
+            dm.dmDisplayOrientation = DMDO_90;
+            break;
+        case DMDO_90:
+            dm.dmDisplayOrientation = DMDO_DEFAULT;
+            break;
+        case DMDO_180:
+            dm.dmDisplayOrientation = DMDO_270;
+            break;
+        case DMDO_270:
+            dm.dmDisplayOrientation = DMDO_180;
+            break;
+        }
+        swap(dm.dmPelsHeight, dm.dmPelsWidth);
+        break;
+    }
+
+    long lRet = lpfnCDS(&dm, 0);
+    return (DISP_CHANGE_SUCCESSFUL == lRet) ? true : false;
+}

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: