How to use EM_INSERTIMAGE? - richedit

Using Visual Studio 2013 Community.
Added #include to source code.
Added Shlwapi.lib to linker.
Compile and link OK.
This is the code that uses EM_INSERTIMAGE:
static void insertimage( )
{
RICHEDIT_IMAGE_PARAMETERS rip;
IStream *pStream = NULL;
DWORD grfMode = STGM_READ | STGM_SHARE_DENY_NONE;
HRESULT hr = SHCreateStreamOnFileA( "add.png", grfMode, &pStream );
if (hr == S_OK)
{
ZeroMemory( &rip, sizeof( rip ) );
rip.xWidth = 2000; // unit 0.01mm
rip.yHeight = 2000;
rip.Type = TA_BASELINE;
rip.pwszAlternateText = L"adding xyz";
rip.pIStream = pStream;
hr = SendMessage( hwndrichedit, EM_INSERTIMAGE, (WPARAM)0, (LPARAM)&rip );
if (hr == S_OK)
{
// getting here, but not getting any image or alternate text
// output on screen
}
}
}
but it does not output any image or alternative text on screen and does not put the image control words into the rtf file.
I also tried SHCreateStreamOnFileEx with same negative result.
How can I make this work?

I forgot to mention I am using Windows 7.
I have been searching Google on EM_INSERTIMAGE and other keys and found
a match that said EM_INSERTIMAGE requires Windows 8. I checked EM_INSERTIMAGE
MSDN and found this in the Requirements section 'Minimum supported client
Windows 8 [desktop apps only]'.
I did not expect this because Wordpad and Windows Office 10 on my Windows 7 PC
can insert images. Also, the Linux TED richedit text editor can insert images
in Ubuntu 12.04 released three years ago.
Maybe these programs just insert the image spec into rtf
as required by the rtf format specification.
I assume EM_INSERTIMAGE issued by a user program would generate the image
rtf part and insert it into the rtf format text.
I am happy with Windows 7 and will not change to Windows 8, so it seems I
will not be able have images.
If EM_INSERTIMAGE only works on Windows 8, I think there should be an error
returned when EM_INSERTIMAGE is issued from Windows 7, Windows XP etc.

EM_INSERTIMAGE is only available from Windows 8 onwards. In Windows 7, you will need to use the RichEdit's OLE interface to insert images. That's how Wordpad does it. You can look up this example on MSDN:
RichEdit OLE sample

Related

Images not appearing on buttons when using old GTK 2 versions

I'm currently testing a GTK 2 version of a program on systems using GTK 2.6, namely Ubuntu 5.04 and Fedora Core 4. I have the issue there that I am unable to create image-only buttons without a label. On later GTK versions (tested with Ubuntu 6.06, Fedora 8 and 10) this works. It looks like this:
Ubuntu 5.04 and Fedora 4 Core:
Ubuntu 6.06 (and similar in Fedora 8 and 10):
I've downloaded GTK 2.6 to find a clue in its documentation, but so far I have not found out why this is happening.
The code I use for image-only buttons is this:
GtkWidget *button = gtk_button_new ();
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON)); // Example
What am I missing here?
(The program is supposed to also run on old and low-end systems, that's why I am bothering with this.)
EDIT
It seems that the behaviour which I had expected was introduced with version 2.8.14, that's why it worked on Ubuntu 6.06 which uses GTK 2.10. This was not obvious to me from reading the documentation.
Packing a stock image into a button by using gtk_container_add() is a way to create labelless image-only buttons when using earlier versions.
Here's the code of gtk_button_set_image as of GTK+ 2.6.9
/**
* gtk_button_set_image:
* #button: a #GtkButton
* #image: a widget to set as the image for the button
*
* Set the image of #button to the given widget. Note that
* it depends on the gtk-button-images setting whether the
* image will be displayed or not.
*
* Since: 2.6
*/
void
gtk_button_set_image (GtkButton *button,
GtkWidget *image)
{
GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
priv->image = image;
priv->image_is_stock = (image == NULL);
gtk_button_construct_child (button);
g_object_notify (G_OBJECT (button), "image");
}
So first we can see that showing images in the buttons is handled by the gtk-buttons-images setting from your gtkrc, so you may need to force this.
We also see that setting a stock icon can be done differently: you can set as the button label the name of the stock icon, and set the use-stock property of the button to TRUE. So maybe you could try that too.

Is there a way to determine Unicode character browser compatibility?

Is there a way to determine unicode compatibility, particularly with newer sets? I want to use the Unicode 6.0 character ❌ (❌), but was not sure which browsers it was compatible with. Searched on caniuse.com, but could not find compatability tables.
This is not a browser issue. Any browser can handle the character ❌, but the user would need to have a font installed that has a shape for it otherwise they'll see some kind of placeholder.
A glyph for U+274C Cross Mark ❌ is supplied as part of fonts bundled with Windows 7, and at least the Android and Ubuntu versions I have here, so that's not bad. If you need to be sure, you can use an embedded font that has such a glyph.
Alternatively there's the very old and well-supported U+00D7 Multiplication Sign ×, or other alternatives.
(There are cases when a browser—or, more specifically, the text layout engine used by the browser—does need to understand what a character is to render it correctly, in addition to having font support. But that's for when characters are added as part of complex scripts like Arabic where characters change their shape in response to context. Not a concern for simple standalone characters like ❌.)
You can check if an emoji is supported by:
Rendering it into a Canvas.
Resizing it to a 1 × 1 to get a single pixel average of it.
Comparing that average value to the one you get when rendering the square character that shows up when an emoji is missing.
Something like this (just a starting point, it just works on Chrome):
function emojiExists(emoji) {
try {
const canvas = document.createElement('CANVAS');
const context = canvas.getContext('2d');
// Set font baseline, size and family:
context.textBaseline = 'top';
context.font = '100px sans-serif';
// Scale so that we get a 1 x 1 representation of the emoji
// (just an average of all the pixels):
context.scale(0.01, 0.01);
// Write the emoji:
context.fillText(emoji, 0, 0);
// Just for testing. Uncoment this line and comment context.scale(...);
// document.body.appendChild(canvas);
// [0, 0, 0, 42] is the value returned for the rectangle character that shows
// up for missing emojis:
return context.getImageData(0, 0, 1, 1).data.join(',') !== '0,0,0,42';
} catch (err) {
// Canvas might not be suported...
}
}
console.log(emojiExists('😃')); // https://emojipedia.org/smiling-face-with-open-mouth/
console.log(emojiExists('💭')); // https://emojipedia.org/right-anger-bubble/
console.log(emojiExists('🛹')); // https://emojipedia.org/skateboard/
console.log(emojiExists('🇨🇳')); // https://emojipedia.org/flag-for-china/
For me, with Chrome Version 63.0.3239.132 (Official Build) (64-bit), I get true, true, false, false, but it doesn't work right in Firefox. It seems to be a known bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1209480
You might need to adapt the code (and change or dynamically calculate the '0,0,0,42' value) when using custom fonts or different browsers.

Why is my CE app refusing to run?

I've been maintaining a Windows CE app for some time now (over a year) and have produced new versions of it from time to time, copying them to the handheld device[s] and running the new versions there.
Today, though, I created a new Windows CE app for the first time. It is a very simple utility.
To create it in VS 2008, I selected a C# "Smart Device Project" template, added a few controls and a bit of code, and built it.
Here are some of the options I selected:
I copied the .exe produced via building the project to the handheld device's Program Files folder:
...but it won't run. Is it in the wrong location? Does it need some ancillary files copied over? Is there some other sort of setup I need to do to get it to run? Or what?
UPDATE
Since there's not much of it, I'm pasting ALL the code below in case somebody thinks my code could be the problem:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace PrinterCommanderCE
{
public partial class PrinterCommanderForm : Form
{
public PrinterCommanderForm()
{
InitializeComponent();
}
private void btnSendCommands_Click(object sender, EventArgs e)
{
SendPrinterCommands();
}
private void SendPrinterCommands()
{
bool successfulSend = false;
const string quote = "\"";
string keepPrinterOn = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}off{0}", quote);
string shutPrinterOff = string.Format("! U1 setvar {0}power.dtr_power_off{0} {0}on{0}", quote);
string advanceToBlackBar = string.Format("! U1 setvar {0}media.sense_mode{0} {0}bar{0}", quote);
string advanceToGap = string.Format("! U1 setvar {0}media.sense_mode{0} {0}gap{0}", quote);
if (radbtnBar.Checked)
{
successfulSend = SendCommandToPrinter(advanceToBlackBar);
}
else if (radbtnGap.Checked)
{
successfulSend = SendCommandToPrinter(advanceToGap);
}
if (successfulSend)
{
MessageBox.Show("label type command successfully sent");
}
else
{
MessageBox.Show("label type command NOT successfully sent");
}
if (ckbxPreventShutoff.Checked)
{
successfulSend = SendCommandToPrinter(keepPrinterOn);
}
else
{
successfulSend = SendCommandToPrinter(shutPrinterOff);
}
if (successfulSend)
{
MessageBox.Show("print shutoff command successfully sent");
}
else
{
MessageBox.Show("print shutoff command NOT successfully sent");
}
}
private bool SendCommandToPrinter(string cmd)
{
bool success = false;
try
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close();
success = true;
}
catch
{
success = false;
}
return success;
}
}
}
UPDATE 2
Based on this, I added a global exception handler to the app so that Program.cs is now:
namespace PrinterCommanderCE
{
static class Program
{
[MTAThread]
static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);
Application.Run(new PrinterCommanderForm());
}
static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
MessageBox.Show(string.Format("GlobalExceptionHandler caught : {0}", e.Message));
}
}
}
Yet running the new build shows nothing - it just "flashes" momentarily with about as much verbosity as Lee Harvey Oswald after Jack Ruby's friendly visit.
UPDATE 3
Could the problem be related to this, and if so, how to solve it?
The circumstance that both my updated version of an existing app AND this brand new and simple app refuse to run indicate there is something fundamentally flawed somewhere in the coding, building, or deployment process.
UPDATE 4
As this is a minimal utility, the reason it (and my legacy, much more involved) app are not working may have something to do with the project properties, how it's being built, a needed file not being copied over, or...???
NOTE: The desktop icon is "generic" (looks like a blank white form); this perhaps indicates a problem, but is it indicative of something awry or is it a minor (aesthetics-only) problem?
UPDATE 5
In Project > Properties..., Platform is set to "Active (Any CPU)" and Platform target the same ("Active (Any CPU)")
I have read that this is wrong, that it should be "x86", but there is no "x86" option available - Any CPU is the only one...?!?
UPDATE 6
In Project > Properties... > Devices, the "Deploy the latest version of the .NET Compact Framework (including Service Packs)" is checked. Is this as it should be?
UPDATE 7
Okay, here's the really strange part of all this:
I have two CF/CE apps that I need to run on these Motorola/Symbol 3090 and 3190 handheld devices.
One is this simple utility discussed above. I find that it actually does run on one of the devices (the 3190, FWIW). So it runs on one device, but not on the other.
HOWEVER, the other (legacy) .exe is the opposite - it runs on the 3090 (where the utility will not even start up), but not on the 3190.
So the utility's needs are met by the 3190, and the legacy util's needs are met by the 3090. However, the NEW version of the legacy app does not run on either device!
I am baffled; I feel as Casey Stengel must have when speaking once of his three catchers: "I got one that can throw but can't catch, one that can catch but can't throw, and one who can hit but can't do either."
UPDATE 8
The 3190 has a newer version of the CF installed; it seems that both the new and the old apps should run on the new device with the newer CE, but they don't - only the one built against/for the new framework does...
UPDATE 9
Here is what the 3090 looks like:
UPDATE 10
So I have two exes, one that runs on the devices (both of them now), and the other that will run on neither of the devices. The two exesw seem almost identical. I compared them with three tools: Red Gates' .NET Reflector; JetBrains' dotPeek, and Dependency Walker.
Here is what I found:
Dependency Walker
Both seem to have the same errors about missing dependencies (I didn't have them in the same folder with their dependent assemblies is probably the problem there)
.NET Reflector
The nonworking file has this entry that the working file does not:
[assembly: Debuggable(0x107)]
Is this the problem and, if so, how can I change it?
JetBrains dotPeek
The References in the working copy of the exe are all version 1.0.50000.0
The non-working exe has an identical list of References, and the same version number.
There is this difference, though:
For the working .exe, dotPeek says, "1.4.0.15, msil, Pocket PC v3.5"
For the non-working .exe, dotPeek says, "1.4.0.15, msil, .Net Framework v4.5"
Is this the problem and, if so, how can I change the non-working .exe to match the working one?
This last is disconcerting, primarily because I see no place in the non-working (newer) version of the project where a "4.5" string exists. Where could dotPeek be getting that information?
UPDATE 11
I do know now that the problem is somewhere between these two MessageBox.Show()s, because the first one I see, but not the second:
public static int Main(string [] args)
{
try
{
// A home-brewed exception handler (named ExceptionHandler()) is already defined, but I'm adding a global one
// for UNHANDLED exceptions (ExceptionHandler() is explicitly called throughout the code in catch blocks).
MessageBox.Show("made it into Main method"); // TODO: Remove after testing <= this one is seen
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(GlobalExceptionHandler);
string name = Assembly.GetExecutingAssembly().GetName().Name;
IntPtr mutexHandle = CreateMutex(IntPtr.Zero, true, name);
long error = GetLastError();
if (error == ERROR_ALREADY_EXISTS)
{
ReleaseMutex(mutexHandle);
IntPtr hWnd = FindWindow("#NETCF_AGL_BASE_",null);
if ((int) hWnd > 0)
{
SetForegroundWindow(hWnd);
}
return 0;
}
ReleaseMutex(mutexHandle);
DeviceInfo devIn = DeviceInfo.GetInstance();
Wifi.DisableWifi();
// Instantiate a new instance of Form1.
frmCentral f1 = new frmCentral();
f1.Height = devIn.GetScreenHeight();
f1.Text = DPRU.GetFormTitle("DPRU HHS", "", "");
MessageBox.Show("made it before Application.Run() in Main method"); // TODO: Remove after testing <= this one is NOT seen
Application.Run(f1);
devIn.Close();
Application.Exit();
return 0;
}
catch(Exception ex)
{
DPRU.ExceptionHandler(ex, "Main");
return 0;
}
} // Main() method
UPDATE 12
More specifically, I've got infinite looping going on somehow; By mashing the "Ent" pill on the handheld device (that's what the button looks like - a "lozenge") - it sounds like gerbils tap-dancing (as debugging MessageBox.Show()s in two methods pop up and are dismissed over and over ad infinitum ad (literally) nauseum).
If an application does not start it is mostly missing something. As you compiled for WindowsCE and CF3.5, the Compact Framework 3.5 runimes have to be installed on the WindowsCE device.
Normally Compact Framework is part of Windows CE images, at least version 1.0, but who knows for your test device? If at least one CF is installed, an app requiring a newer CF version will show that on start by a message stating about the missed version. So either no CF is on your device, or something is goind real wrong.
You can run \Windows\cgacutil.exe to check the CF version installed on the device. The tool will show the version of installed CF.
You can debug using a TCP/IP connection or ActiveSync connection. See remote debuggung elsewhere in stackoverflow, I wrote a long aanswer about remote debug via TCP/IP. Or does your device neither have USB and WLAN or ENET?
Update: Here is the answer for remote debug via tcp/ip: VS2008 remotely connect to Win Mobile 6.1 Device This will also enable the remote deployment "In Project > Properties... > Devices, the "Deploy the latest version of the .NET Compact Framework (including Service Packs)" is checked. Is this as it should be?"
Are the earlier apps you wrote also written .NET? Compact framework does not care about the processor architecture, only the CF runtimes have to match the processor. So you do not need an x86 target as if you write a native C/C++ SmartDevice project.
To your comments:
a) CF1.0 is installed on the device.
b) the exe built on the colleagues computer seems to be built for CF1 and therefor runs OK.
c) your exe is built for CF 3.5 and does not run as there is no CF3.5 runtime on the device.
d) most CF exe files are very small as long as they do not include large resources or ...
Conclusion so far: Install the CF3.5 runtime onto the device: http://msdn.microsoft.com/en-us/library/bb788171%28v=vs.90%29.aspx.
To run the legacy app on both devices, the referenced Motorola or other 3rd party runtimes must also be installed. I stringly recommand to setup your environment so you can use ActiveSync/WMDC for development, deployment and debugging of the device. If you are unable look for some more experienced colleague.
Can you try to run it inside the debugger and check where it fails?
Can you place a breakpoint right at the beginning of Program.main and check if it's reached?
Debug output may also give you some interesting hints.

IMFSourceReader giving error 0x80070491 for some resolutions

I'm trying to catpure video from a 5MP UVC camera using an IMFSourceReader from Microsoft Media Foundation (on Windows 7 x64). Everything works just like the documentation with no errors on any API calls until the first callback into OnReadSample() which has "0x80070491 There was no match for the specified key in the index" as it's hrStatus parameter.
When I set the resolution down to 1080p it works fine even though 5MP is the camera's native resolution and 5MP (2592x1944) enumerates as an available format.
I can't find anything in the the Microsoft documentation to say that this behaviour is by design but it seems consistent so far. Has anyone else got IMFSourceReader to work at more that 1080p?
I see the same effects on the Microsoft MFCaptureToFile example when it's forced to select the native resolution:
HRESULT nativeTypeErrorCode = S_OK;
DWORD count = 0;
UINT32 streamIndex = 0;
UINT32 requiredWidth = 2592;
UINT32 requiredheight = 1944;
while ( nativeTypeErrorCode == S_OK )
{
IMFMediaType * nativeType = NULL;
nativeTypeErrorCode = m_pReader->GetNativeMediaType( streamIndex, count, &nativeType );
if ( nativeTypeErrorCode != S_OK ) continue;
// get the media type
GUID nativeGuid = { 0 };
hr = nativeType->GetGUID( MF_MT_SUBTYPE, &nativeGuid );
if ( FAILED( hr ) ) return hr;
UINT32 width, height;
hr = ::MFGetAttributeSize( nativeType, MF_MT_FRAME_SIZE, &width, &height );
if ( FAILED( hr ) ) return hr;
if ( nativeGuid == MFVideoFormat_YUY2 && width == requiredWidth && height == requiredheight )
{
// found native config, set it
hr = m_pReader->SetCurrentMediaType( streamIndex, NULL, nativeType );
if ( FAILED( hr ) ) return hr;
break;
}
SafeRelease( &nativeType );
count++;
}
Is there some undocumented maximum resolution with Media Framework?
It turns out that the problem was with the camera I was using, NOT the media streaming framework or UVC cameras generally.
I have switched back to using DirectShow sample grabbing which seems to work ok so far.
I ran into this same problem on windows 7 with a usb camera module I got from Amazon.com (ELP-USBFHD01M-L21). The default resolution of 1920x1080x30fps (MJPEG) works fine, but when I try to select 1280x720x60fps (also MJPEG, NOT h.264) I get the 0x80070491 error in the ReadSample callback. Various other resolutions work OK, such as 640x480x120fps. 1280x720x9fps (YUY2) also works.
The camera works fine at 1280x720x60fps in Direct Show.
Unfortunately, 1280x720x60fps is the resolution I want to use to do some fairly low latency augmented reality stuff with the Oculus Rift.
Interestingly, 1280x720x60fps works fine with the MFCaptureD3D sample in Windows 10 technical preview. I tried copying the ksthunk.sys and usbvideo.sys drivers from my windows 10 installation to my windows 7 machine, but they failed to load even when I booted in "Disable Driver Signing" mode.
After looking around on the web, it seems like various people with various webcams have run into this problem. I'm going to have to use DirectShow to do my video capture, which is annoying since it is a very old API which can't be used with app store applications.
I know this is a fairly obscure problem, but since Microsoft seems to have fixed it in Windows 10 it would be great if they backported the fix it to Windows 7. As it is, I can't use their recommended media foundation API because it won't work on most of the machines I have to run it on.
In any case, if you are having this problem, and Windows 10 is an option, try that as a fix.
Max Behensky

Printing Receipt on Star Micronics TSP 650 Printer through iPad

I am using Star iOS SDK to print receipts (like a restaurant bill) but am facing problems implementing column settings and cell spacing for proper alignment. I have checked out the documentation but have not found something useful.
The line code manual has some signals/commands which I am unable to understand. Can anyone help me out with that?
The commands referenced in the Line Mode manual need to be converted into bytes and then sent to the printer. The StarIO iOS SDK package you downloaded has a manual called "README_StarIO_POSPrinter_iOS_SDK.pdf". (http://www.starmicronics.com/absolutefm/absolutefm/afmviewfaq.aspx?faqid=175) Did you check out pages 9-15? The StarIO framework is explained here.
Specific to your question about sending commands, page 13 shows you how to write to the port using a byte array, but make sure you add StarIO.framework and open the communication port first.
From the manual:
//Set a byte array to send to the printer
//command = { A, B, C, D, Feed 3mm, Full Cut}
unsigned char command = {0x41, 0x42, 0x43, 0x44, 0x1B, 0x7A, 0x00, 0x1B, 0x64, 0x02};
Uint bytesWritten = 0;
#Try
{
While(bytesWritten < (sizeof command))
{
bytesWritten += [port writePort: command : bytesWritten : sizeof command - bytesWritten];
}
}
#Catch(PortException)
{
//There was an error writing to the port
}
Also described is how to close ports (make sure you close every opened port) and getting printer status.
Let me know if this helps.
I talked to SDK developers of start micronics, as I was facing the same problem using TSP100 model. Here is the reply from one of their tech guy.
"Unlike most of our other models the TSP100 series is a bit unique in that it is raster only meaning that it does not have the text formatting commands that our other printers do (ie, the printer just prints whatever receipt image you send it). Any formatting would be done in your application however you would like to do it before creating the image to send to the printer"
So this is clear that you have to maintain the column width, formatting, alignment etc everything by yourself.