How can I determine if F15 has been pressed? - regex

I have a little console application that among other things checks the status of another operation. Once a second it checks for keypresses using Term::ReadKey. If the 'r' key has been pressed, it refreshes the display:
{ # generate display ...
print "Press 'r' to refresh, any other key to exit: ";
my $resp = readkey();
print $resp;
redo if $resp =~ /r/i;
}
exit;
sub readkey {
my $key;
ReadMode('cbreak');
while (not defined $key) {
if (defined ($key = ReadKey(-1)) ) {
exit if $key =~ /\cC/i; # allow Ctrl-C to behave normally
return $key;
} else {
sleep 1;
}
}
ReadMode('normal');
}
This all works exactly as intended. However, I also use Caffeine to keep my Win 7 display from going to sleep. This utility works by simulating a press of F15 every 59 seconds, thereby never allowing the screensaver to kick in. Although Caffeine's approach is pretty kludgy it has worked very well for me for years. However, like Windows my console app also reads the simulated press of F15 as a real keypress, causing the console app to exit. If I could match against F15, I could filter it out. So, my question:
How can I determine if F15 has been pressed, using Term::ReadKey?
This is on Windows 7 Pro, Strawberry 5.12.3, Term::ReadKey v. 2.30.02.
(I am aware that there may be a significant x-y problem component to my question, and I welcome other solutions. However, I am curious about how one would do this. I can see why I might want to see when a function key has been pressed in other situations.)

[It's good that you recognize that this is very xy :)]
You're using a unix-centric module. Use a more appropriate module: Win32::Console, for example.
[My earlier answer got converted to a comment. Apparently, the Stack Overflow mods wants my answer to be 99% repeated content?!?]
my $con_in = Win32::Console->new(STD_INPUT_HANDLE);
for (;;) {
my #event = $con_in->Input();
my $event_type = shift(#event);
next if !defined($event_type) || $event_type != 1; # 1: Keyboard
my ($key_down, $repeat_count, $vkcode, $vscode, $char, $ctrl_key_state) = #event;
if ($vkcode == VK_F15 && ($ctrl_key_state & SHIFTED_MASK) == 0) {
if ($key_down) {
say "<Up> pressed/held down" for 1..$repeat_count;
} else {
say "<Up> released";
}
}
}
See KEY_EVENT_RECORD for more information about keyboard events.
See Virtual-Key Codes to identify keys.
Headers and definitions for above code:
use strict;
use warnings;
use feature qw( say );
use Win32::Console qw( STD_INPUT_HANDLE );
use constant {
RIGHT_ALT_PRESSED => 0x0001,
LEFT_ALT_PRESSED => 0x0002,
RIGHT_CTRL_PRESSED => 0x0004,
LEFT_CTRL_PRESSED => 0x0008,
SHIFT_PRESSED => 0x0010,
VK_F15 => 0x7E,
};
use constant SHIFTED_MASK =>
RIGHT_ALT_PRESSED |
LEFT_ALT_PRESSED |
RIGHT_CTRL_PRESSED |
LEFT_CTRL_PRESSED |
SHIFT_PRESSED;

Related

Error "emit without supply or react" when tapping IO::Notifications

These nested supplies cause an error, but apparently only if the internal supply is IO::Notification. It does not seem to be a problem for any other supply:
my $supply = IO::Notification.watch-path( "/var/log/syslog" );
my $parsed = supply {
$supply.tap: -> $v {
emit( { Seen => $v.event } );
CATCH {
default {
$*ERR.say: .message;
}
}
}
}
$parsed.tap( -> $v { say $v });
sleep 40;
This is the error emitted:
emit without supply or react
emit without supply or react
(when there's a event that fires the supply). I haven't been able to reproduce it in other kind of nested supplies, but this always fails. Any idea why?
You must use whenever to subscribe to $supply, otherwise the subscription won't be associated with the supply block (and so, aside from emit not working, also won't get concurrency control, subscription management, and so forth).
my $supply = IO::Notification.watch-path( "foo" );
my $parsed = supply {
# Solution: use `whenever` here
whenever $supply -> $v {
emit( { Seen => $v.event } );
CATCH {
default {
$*ERR.say: .message;
}
}
}
}
$parsed.tap( -> $v { say $v });
sleep 40;
(About it perhaps sometimes working out: if you subscribe to something that produces values synchronously after tapping, the emit handler would be in dynamic scope of the setup phase of the supply block, so in that case it may appear to work.)

Memory leak in concurrent program, or just the way it is?

This is a simplified version of a program which has two channels to carry out some operation
use v6;
my $length = 512;
my Channel $channel-one .= new;
my Channel $to-mix .= new;
my Channel $mixer = $to-mix.Supply.batch( elems => 2).Channel;
my #promises;
for ^4 {
$channel-one.send( 1.rand xx $length );
my $promise = start react whenever $channel-one -> #crew {
my #new-crew = #crew;
#new-crew[#new-crew.elems.rand] = 1;
if ( sum(#new-crew) < $length ) {
say "Emitting in thread ", $*THREAD.id, " Best ", sum(#crew) ;
$to-mix.send( #new-crew );
} else {
say "Found: closing";
$channel-one.close;
say "Closed";
};
}
#promises.push: $promise;
}
my $pairs = start react whenever $mixer -> #pair {
$to-mix.send( #pair.pick ); # To avoid getting it hanged up
my #new-population = crossover-frequencies( #pair[0], #pair[1] );
$channel-one.send( #new-population);
say "Mixing in ", $*THREAD.id;
};
await #promises;
say "Finished";
# Cross over frequencies
sub crossover-frequencies( #frequencies, #frequencies-prime --> Array ) is export {
my #pairs = #frequencies Z #frequencies-prime;
my #new-population = gather {
for #pairs -> #pair {
take #pair.pick;
}
};
return #new-population;
}
It uses one channel for performing some operation (here simplified to setting a random element to one) and another for mixing elements taken in pairs. It works and finishes after a while, but for indicated sizes it starts to grow in memory usage until it reaches almost 1GB before ending.
It might be to-mix channel which is growing, but I don't see it as the source of the leak, since it's getting one element from one block, and one from the other; there might be a few left on the channel before finishing, but not so many as to justify the memory hogging. Any other idea?
An additional problem is that it seems to be always using the same thread for "processing", despite the fact that 4 different threads have been started. I don't know if this is related or not.

c# windows form - How received a tag value data into my textbox1?

<input name="chkFile" value="2062223616_7147073260_1440589192619132.WMA" type="checkbox">
from this code I want only the value data
Example:
2062223616_7147073260_1440589192619132.WMA
below my code not working so please help me.
My code
HtmlElementCollection bColl = webBrowser2.Document.GetElementsByTagName("input");
foreach (HtmlElement bEl in bColl)
{
if (bEl.GetAttribute("name").Equals("chkFile"))
showaudiourl.Text = bEl.OuterHtml.Split('"')[3];
}
Use webBrowser2.GetAttribute("value") to get the value you want.
HtmlElementCollection bColl = webBrowser2.Document.GetElementsByTagName("input");
foreach (HtmlElement bEl in bColl) {
if (bEl.GetAttribute("name").Equals("chkFile")) {
showaudiourl.Text = bEl.GetAttribute("value"); //Changes here
}
}
All you need is add a piece of code telling the app to wait until the web browser document gets initialized:
webBrowser2.Navigate(#"C:\tmp.html"); // Use your own URL here
while (webBrowser2.ReadyState != WebBrowserReadyState.Complete) // Without it,
Application.DoEvents(); // the document will be null
HtmlElementCollection bColl = webBrowser2.Document.GetElementsByTagName("input");
foreach (HtmlElement bEl in bColl)
{
if (bEl.GetAttribute("name").Equals("chkFile"))
showaudiourl.Text = bEl.GetAttribute("value");
}
The value should be accessed with bEl.GetAttribute("value").
Alternatively, you could use a webBrowser2_DocumentCompleted event to process the HTML document there.

Hide product description

How can I hide product description when the description is long in Opencart (product page) to reduce the load product page, but after clicking on the detail link then came out a full description.
In image you can see Example, Sorry for my bad english, Thanks!
Here is a link to example image example
Why not just truncate it? It will force it to be the right length for you every time!
Go to catalog/controller/product/category.php and when you see
foreach ($results as $result) {
if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $this->config->get('config_image_product_width'), $this->config->get('config_image_product_height'));
} else {
$image = false;
}
Add this next:
function truncate($description, $tLimit="20", $break=" ", $pad="...")
{
if(strlen($string) <= $tlimit) return $string;
if(false !== ($breakpoint = strpos($string, $break, $tlimit))) {
if($breakpoint < strlen($string) - 1) {
$string = substr($string, 0, $breakpoint) . $pad;
}
}
return $description;
}
Feel free to change the variables:
$tLimit is how many letters you want to allow it.
$break is where you want it to cut off, right now it is set to cut off at the next space. You can have it interrupt words if you like by putting $break=""
$pad is what you want it to show after it cuts off the text.
If you really want no description to show at all Then I recommend still doing something similar to the original script.
function getDescriptionLength($description, $tLimit="20")
{
if(strlen($string) <= $tlimit) return $string;
else {
$description = NULL;
}
return $description;
}

Perl Win32::API and Pointers

I'm trying to utilize the Win32 API function DsGetSiteName() using Perl's Win32::API module. According to the Windows SDK, the function prototype for DsGetSiteName is:
DWORD DsGetSiteName(LPCTSTR ComputerName, LPTSTR *SiteName)
I successfully wrote a small C++ function using this API to get a better understanding of how it would actually work (I'm learning C++ on my own, but I digress).
Anyhow, from my understanding of the API documentation, the second parameter is supposed to be a pointer to a variable that receives a pointer to a string. In my C++ code, I wrote that as:
LPSTR site;
LPTSTR *psite = &site;
and have successfully called the API using the psite pointer.
Now my question is, is there a way to do the same using Perl's Win32::API? I've tried the following Perl code:
my $site = " " x 256;
my $computer = "devwin7";
my $DsFunc = Win32::API->new("netapi32","DWORD DsGetSiteNameA(LPCTSTR computer, LPTSTR site)");
my $DsResult = $DsFunc->Call($computer, $site);
print $site;
and the result of the call in $DsResult is zero (meaning success), but the data in $site is not what I want, it looks to be a mixture of ASCII and non-printable characters.
Could the $site variable be holding the pointer address of the allocated string? And if so, is there a way using Win32::API to dereference that address to get at the string?
Thanks in advance.
Win32::API can't handle char**. You'll need to extract the string yourself.
use strict;
use warnings;
use feature qw( say state );
use Encode qw( encode decode );
use Win32::API qw( );
use constant {
NO_ERROR => 0,
ERROR_NO_SITENAME => 1919,
ERROR_NOT_ENOUGH_MEMORY => 8,
};
use constant PTR_SIZE => $Config{ptrsize};
use constant PTR_FORMAT =>
PTR_SIZE == 8 ? 'Q'
: PTR_SIZE == 4 ? 'L'
: die("Unrecognized ptrsize\n");
use constant PTR_WIN32API_TYPE =>
PTR_SIZE == 8 ? 'Q'
: PTR_SIZE == 4 ? 'N'
: die("Unrecognized ptrsize\n");
# Inefficient. Needs a C implementation.
sub decode_LPCWSTR {
my ($ptr) = #_;
return undef if !$ptr;
my $sW = '';
for (;;) {
my $chW = unpack('P2', pack(PTR_FORMAT, $ptr));
last if $chW eq "\0\0";
$sW .= $chW;
$ptr += 2;
}
return decode('UTF-16le', $sW);
}
sub NetApiBufferFree {
my ($Buffer) = #_;
state $NetApiBufferFree = Win32::API->new('netapi32.dll', 'NetApiBufferFree', PTR_WIN32API_TYPE, 'N')
or die($^E);
$NetApiBufferFree->Call($Buffer);
}
sub DsGetSiteName {
my ($ComputerName) = #_;
state $DsGetSiteName = Win32::API->new('netapi32.dll', 'DsGetSiteNameW', 'PP', 'N')
or die($^E);
my $packed_ComputerName = encode('UTF-16le', $ComputerName."\0");
my $packed_SiteName_buf_ptr = pack(PTR_FORMAT, 0);
$^E = $DsGetSiteName->Call($packed_ComputerName, $packed_SiteName_buf_ptr)
and return undef;
my $SiteName_buf_ptr = unpack(PTR_FORMAT, $packed_SiteName_buf_ptr);
my $SiteName = decode_LPCWSTR($SiteName_buf_ptr);
NetApiBufferFree($SiteName_buf_ptr);
return $SiteName;
}
{
my $computer_name = 'devwin7';
my ($site_name) = DsGetSiteName($computer_name)
or die("DsGetSiteName: $^E\n");
say $site_name;
}
All but decode_LPCWSTR is untested.
I used the WIDE interface instead of the ANSI interface. Using the ANSI interface is needlessly limiting.
PS — I wrote the code to which John Zwinck linked.
I think you're right about $site holding the address of a string. Here's some code that demonstrates the use of an output parameter with Perl's Win32 module:
http://www.perlmonks.org/?displaytype=displaycode;node_id=890698