Borbin the 🐱

Encrypt your data

30 January, 2014


Sending data over the Internet is not safe. A safe connections takes effort and resources.
If you manage to get your mail send via encryption, you forgot the National Security Agencies (in short NSA) that have access to the mail servers and scan your data before its gets send encrypted over the Internet. Move your data up to an online storage leaves them in a container that is not yours alone.

But if you encrypt and decrypt data on your computer first with a strong 256bit encryption key, you can leave any security agency in the dark.
These Windows Powershell script functions makes it easy to encrypt and decrypt your files.
Since it is a symmetrical cipher, the same password is used for encryption and decryption.
If you need to pass your large secure data to another receiver, pass on the script with the new secret password and sentences using an unsymmetrical cipher or an alternative transport (mail / USB stick). The reward is a secure data transmission.

For example encrypt a file with the script:

Encrypt-File "C:\data\mydata.zip"

Send this encrypted file to an online storage or send via mail.
Receive the file and decrypt with the same script password:

Decrypt-File "C:\download\mydata.zip"


If you intent to encrypt/decrypt pictures, you can use the script plugins in cPicture.

Download

Encrypt-Decrypt Script
(remove the trailing .txt from the file once it is downloaded)

Note

Change the secret phrases and password in the script.
Select the script function you want to use at the bottom of the script or add the script to an existing upload/download process.


'Encountered an improper argument.'

11 March, 2013


Ever run into this error message?

The error message 'Encountered an improper argument.' is from an uncaught exception in WindowProc.

In:

LRESULT CWinApp::ProcessWndProcException(CException* e, const MSG* pMsg)
    e->ReportError(MB_ICONEXCLAMATION|MB_SYSTEMMODAL, nIDP);

the error message is nIDP = AFX_IDP_INTERNAL_FAILURE:

#define AFX_IDP_INTERNAL_FAILURE        0xF108      // general failure

Usually you don't end up here. But there are cases where it happens. I have one example which was difficult to debug: An existing MFC based app upgraded to a ribbon control using a release build with static linking. Dynamic linked release builds and all debug builds are not affected.


It all starts at the InitInstance()of your app when you load the main frame:

pFrame->LoadFrame(IDR_MAINFRAME,
  WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
  NULL);

Then all the way down the call stack:

BOOL CFrameWndEx::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)


BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
  CWnd* pParentWnd, CCreateContext* pContext)

BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
  LPCTSTR lpszWindowName,
  DWORD dwStyle,
  const RECT& rect,
  CWnd* pParentWnd,
  LPCTSTR lpszMenuName,
  DWORD dwExStyle,
  CCreateContext* pContext)

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
  LPCTSTR lpszWindowName, DWORD dwStyle,
  int x, int y, int nWidth, int nHeight,
  HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)

until you reach:

ISOLATION_AWARE_INLINE HWND IsolationAwarePrivatenCv IsolationAwareCreateWindowExW(_In_ DWORD dwExStyle,_In_opt_ LPCWSTR lpClassName,_In_opt_ LPCWSTR lpWindowName,_In_ DWORD dwStyle,_In_ int X,_In_ int Y,_In_ int nWidth,_In_ int nHeight,_In_opt_ HWND hWndParent,_In_opt_ HMENU hMenu,_In_opt_ HINSTANCE hInstance,_In_opt_ LPVOID lpParam)

At this point you suddenly end up in the exception handler of the WndProc:

LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg,
  WPARAM wParam = 0, LPARAM lParam = 0)

All class names, handles and sizes look alright. The last message is 5, which is a WM_SIZE message with the right lParam value. Usually you get a debug break and know why the exception was raised, but here it seemed a mystery. But a quick compare to a sample app from the templates revealed the solution: The ribbon required additional resources in order to run in a static release build in the .rc file:

#if !defined(_AFXDLL)
  #include "l.DEU\afxprint.rc"         // Ressourcen für Drucken/Seitenansicht
  #include "l.DEU\afxribbon.rc"        // Ressourcen für MFC-Menüband und -Steuerleiste
#endif

(Remove the language prefix 'l.DEU\' with your language code if you are building another language.)


Web page with inline image

07 March, 2013


To add an image to a web page you use the img tag.
<img src="your-image.png" alt="your-image" />
Simple as that. But you need to use a binary file.

If you work on an embedded system, a html control with restrictions or simply need one plain html file, you can use images inline. The picture data will be encoded with text characters (base64) and added as a class:

<style type="text/css">
    .my-picture
    {
        background-image: url(data:image/png;base64, BASE64 DATA );
        height: 24px;
        width: 24px;
        display: block;
    }
</style>

Later on, you reference the picture class to display the image:

<div class="my-picture"></div>



sample

Here is a complete HTML sample:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>base64 image/png</title>
    <style type="text/css">
        .back-button
        {
            background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADb0lEQVRIx52WT2hcVRTGf+fORJMgbYVEWv9uhEBaEpoMEem8DEKtm0qrWLCLItJFFyJIG5CIC12ni3ZhVRCKUEqJ1EVduNHUlzupm5k4Bptu1FUZwRhNTTMhNe9+LuYlDclMk/Rs3uXdc7/z3nfOd841mliUzz+GWbdBL3AQ6BTsAszgDjADjAkqSDd9sfhvIxxb/2IwiloEXcDbVn/eBaaAKjCXuu0E9gA9wA5Jv2F2EbjlvV9qGqBQKLgQwiGDYeAPpMsym3TOVeM4Dg18d5vUCxyX2fPAWZck1+IbN5Y3BCgUCi4kyRBwFLjki8ULbMOifP4tMzsl6bqTPoonJv4DcCu0hBAOAUcx+8zgS7ZrZqPAOTN7KTh3JIqi1tUAgq6UlksmXR0vFhe2i++9XxR8g/QpMATsBbC0Wj42eGrc+zcbHR4YGDAzywA2Pz+/PD09rQcFG8znvxDcw+wDl5ZiF9LlZgdCCC8mSTKcJMlJILPZ38jsipk9B/S6tM7vymyykXMul3saOAecAGpAsilf0hQwa9CXTUX0s3Ouug44A+SBkTRX79Rqte82owfAZTIzCmESeDkLdAIb6jwF/xB4RtIZ4FZbW1tHf39/M9xauVxeAIjjWINRVBV0ZAW77L5C19IyAuwHZszstVQfVi+6VQ2tXY8CX62hac7MdjnA6b5juqdW4JF1irdN1hsyAVjW4J+0t6xauVz+NZfLnaGujb2SvgbGgXsPoH5hnfB2CuaywF/Ak4VCwa3Lww/AMjBiZqeBP2u12vdbSXJqewxmHTAG9IQQdq/dLZVKSalUioHXgQBcaG9vP9Hd3W1b6EsdQB8w5gQVYEfaFTdYqVS6DZwGrgJPtLa2tmyhL+1L50c5i3RT8LvBceDbxv42IakkKZPNZpe3QM8xSVUzqxhAFEX7gU+QPsds1Hu/yENYFEWPmnRYMIzZu977H126Nw2cNbNTBq9GUdT2UODwCvWCOG8hVFbbtfd+ySXJNUnXgfdMemPb40A6DLwP/CQYHZ+YWNw4Mg8caAnOHQGGTPpFZleQplwmMxPHsRpWSz2hx5BeAM4LRovF4lLToZ9Oon1IJ83sWWAWmARuI91ZEVE69PuATklVzC5aCJWVL28aYE2gx4Eeq4McFHRYem0RzFk98JigbFAZ9/7vRjj/A6BAc6F41EmIAAAAAElFTkSuQmCC);
            height: 24px;
            width: 24px;
            display: block;
        }
    </style>
</head>
<body>
    <p>This is a back button</p>
    <div class="back-button"></div>
</body>
</html>

To convert between picture files and base64 data, you can use these PowerShell lines

From a file (for example 'p24.png') to base64 data:

$bin = Get-Content p24.png -Encoding Byte
$str = [System.Convert]::ToBase64String($bin)

From base64 data to a file (for example 'p24.png')

$str = "your BASE64 DATA"
$bin = [System.Convert]::FromBase64String($str)
Set-Content p24.png -Encoding Byte -Value $bin

Simple as that, but keep the image size small.


CMFCRibbonBar: change tooltips at runtime

23 February, 2013


Tooltips gets displayed as the string part after the '\n' char of the matching resource. So in case you were wondering why you don't see tooltips in your new ribbon if you use your existing string IDs, add the newline to the string resource. But how to change tooltips of the MFC ribbon bar at runtime?
Using the OnToolTipNotify doesn't work with the MFC ribbon bar because no IDs are used.

But here is a trick to make it work:
Derive a new class from the CMFCRibbonBar class to override the TTN_NEEDTEXT message.

class CMyRibbonBar : public CMFCRibbonBar
{
protected:
    //{{AFX_MSG(CMyRibbonBar)
    afx_msg BOOL OnNeedTipText(UINT id, NMHDR* pNMH, LRESULT* pResult);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};


Set the TTN_NEEDTEXT message handler.

BEGIN_MESSAGE_MAP(CMyRibbonBar, CMFCRibbonBar)
    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, &CMyRibbonBar::OnNeedTipText)
END_MESSAGE_MAP()


The new TTN_NEEDTEXT message handler gets the original tooltip text, modify the text and sends back the new tooltip text. The MFC ribbon bar does not send the resource ID of the tool. Because of this, the tooltips are matched by string content.

BOOL CMyRibbonBar::OnNeedTipText(UINT id, NMHDR* pNMH, LRESULT* pResult)
{
    static CString strTipText;

    // get tooltip text
    BOOL ret = CMFCRibbonBar::OnNeedTipText(id, pNMH, pResult);

    LPNMTTDISPINFO pTTDispInfo = (LPNMTTDISPINFO)pNMH;
    strTipText = pTTDispInfo->lpszText;

    // modify tooltip text
    CString strRes;
    strRes.LoadString(ID_MY_UI_ELEMENT);
    strRes.TrimLeft(_T('\n'));

    if(strTipText == strRes)
    {
        // new content for ID_MY_UI_ELEMENT
        strTipText = "New tool tip content\r2nd Line";
        pTTDispInfo->lpszText = const_cast<LPTSTR>((LPCTSTR)strTipText);
    }

    return ret;
}


To set tooltip for the drop down menus, simply get the element via the ID, and use the SetToolTipText API. Here is an example on how it is done for the plugins menu in cPicture:

    // Add the tooltips.
    for (vector<FunctionPlugin>::const_iterator it = CRegisterFunctionPlugin::s_vec_function_plugin.begin(); it != CRegisterFunctionPlugin::s_vec_function_plugin.end(); ++it)
    {
        const UINT i(static_cast<UINT>(it - CRegisterFunctionPlugin::s_vec_function_plugin.begin()));

        CMFCRibbonBaseElement* pElement = FindByID(ID_FUNCTION_PLUGINS_START + i, FALSE, TRUE);
        if (pElement)
        {
            pElement->SetToolTipText(it->pluginData.desc);
        }
    }

Unix time in PowerShell

05 February, 2013


The Unix time is the number of seconds since 1 January 1970.
In PowerShell:

((Get-Date "02/05/2013") - (Get-Date "01/01/1970")).TotalSeconds

1360022400

To get back the date from the number of seconds, use:

(Get-Date "01/01/1970").AddSeconds(1360022400)

2/5/2013 12:00:00 AM



If your system has a different locale, use the culture specific writing. For example using German ('de-DE'):

((Get-Date "05.02.2013") - (Get-Date "01.01.1970")).TotalSeconds

1360022400

(Get-Date "01.01.1970").AddSeconds(1360022400)

Dienstag, 5. Februar 2013 00:00:00



In case you have a format in a locale that is different from your PowerShell locale:

$DateTime = [DateTime]::Parse("05/02/2013", [System.Globalization.CultureInfo]'fr-FR')
($DateTime - (Get-Date "01.01.1970")).TotalSeconds

Note the difference between french and american date order: 05/02/2013 - 02/05/2013


Redirect HTML pages

05 February, 2013


Redirect web pages is common practice and often done with the meta tag refresh, but there are drawbacks and it is not recommended by the W3C. Using a HTTP redirection status code is preferred, but often simply not practical.
If you have a page http://oldsite.com/project/index.html and you need a redirect to http://mysite.com/project/, you simply place this index.html in http://oldsite.com/project/. In case JavaScript is disabled, the default meta refresh is used as a default:

index.html

<!DOCTYPE HTML>
<html>
<head>
    <title></title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <meta http-equiv="refresh" content="1; URL=http://mysite.com/project/" />
    <script type="text/javascript">
        window.location.href = "http://mysite.com/project/"
    </script>
</head>
<body>
</body>
</html>

Neuere Beiträge →← Vorherige Beiträge