SetWindowPos behaviour for Notepad.exe on multi-moniter setup - winapi

I am trying to move the Notepad window using the SetWindowPos() Win32 API.
When I pass x/left = -1, instead of only moving the window in x-direction, it also changes the y/top of the window (window sort of creeps upward). This only happens in a multi-monitor setup.
x=0 multi-monitor:
x=-1 multi-monitor:
In a single monitor setup, it is moving the window in the x-direction as expected:
x=-1 single-monitor:
Also, I created my own simple window (using Visual Studio's wizard-generated code) and it works as expected (y/top did not change) even in a multi-monitor setup.
x=0 multi-monitor:
x=-1 multi-monitor:
I observed the same behaviour in Chrome/Brave/MSEdge windows as well in a multi-monitor setup.
I tried to install WH_CALLWNDPROC and WH_GETMESSAGE hooks, and used Spy++, but I didn't get any useful information about what is happening.
TEST:
Make sure notepad.exe is running.
For simplicity, I will use Python and will require win32gui and win32con
pip install pywin32
import win32gui
import win32con
notepadHwnd = win32gui.FindWindow("Notepad", None)
// => x = 0
win32gui.SetWindowPos(notepadHwnd, win32con.HWND_TOP, 0, 200, 200, 100, win32con.SWP_NOREDRAW)
win32gui.GetWindowRect(notepadHwnd)
// (0, 200, 200, 300)
// => x = -1
win32gui.SetWindowPos(notepadHwnd, win32con.HWND_TOP, -1, 200, 200, 100, win32con.SWP_NOREDRAW)
win32gui.GetWindowRect(notepadHwnd)
// (-1, 160, 199, 300) 160??????????????
Is this behaviour implementation-specific? Any explanation as to why this is the case?
Both of the monitors are 1920x1080.
Update:
The y/top parameters effects how much y/top itself gets changed when x=-1 is specified e.g.
when y=0, then change in y'=0
>>> win32gui.SetWindowPos(notepadHwnd, win32con.HWND_TOP, -1, 0, 200, 100, win32con.SWP_SHOWWINDOW)
>>> win32gui.GetWindowRect(notepadHwnd)
(-1, 0, 199, 100)
when y=60, then change in y'=48
>>> win32gui.SetWindowPos(notepadHwnd, win32con.HWND_TOP, -1, 60, 200, 100, win32con.SWP_SHOWWINDOW)
>>> win32gui.GetWindowRect(notepadHwnd)
(-1, 48, 199, 160)
when y=600, then change in y'=480
>>> win32gui.SetWindowPos(notepadHwnd, win32con.HWND_TOP, -1, 600, 200, 100, win32con.SWP_SHOWWINDOW)
>>> win32gui.GetWindowRect(notepadHwnd)
(-1, 480, 199, 700)

Related

d3.scaleLog ticks with base 2

I trying to produce ticks for scaleLog().base(2).
Seems to be, it does not work correctly.
For instance, for the call:
d3.scaleLog().base(2).domain([50,500]).ticks(10)
I got:
[ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500 ]
Which just linear placed ticks. For base(10) it works properly.
d3.scaleLog().base(10).domain([50,500]).ticks(10)
[ 50, 60, 70, 80, 90, 100, 200, 300, 400, 500 ]
I using d3.js version 6.1.1.
I am missing something?
You're not missing anything, but there is this line, inside the source code:
if (z.length * 2 < n) z = ticks(u, v, n);
Here, z is the generated array (in this case [64, 128, 256]), n is the required number of ticks (10), and u and v are the domain (50 and 500).
Because the number of generated ticks is too low, d3 defaults to a linear scale. Try one of the following instead:
console.log(d3.scaleLog().base(2).domain([50, 500]).ticks(6));
console.log(d3.scaleLog().base(2).domain([32, 512]).ticks(10));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.1/d3.min.js"></script>
If all parameters are variable, you could calculate the maximum possible number of ticks and use that as an upper bound:
const domain = [50, 500];
const ticks = 100;
console.log(d3.scaleLog().base(2).domain(domain).ticks(ticks));
function getNTicks(domain, ticks) {
const maxPossibleTicks = Math.floor(Math.log2(domain[1]) - Math.log2(domain[0]));
return Math.min(ticks, maxPossibleTicks);
}
console.log(d3.scaleLog().base(2).domain(domain).ticks(getNTicks(domain, ticks)));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.1/d3.min.js"></script>

Dynamic image cropping in Tensorflow

I'm trying to figure out how to take a crop of an image determined dynamically in Tensorflow. Below is an example of what I am trying to accomplish, however I can't seem to make it work. Essentially, I want to feed images and the crop values for that image within the graph, and then continue on with other computations on those cropped pieces. My current attempt:
import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np
sess = tf.InteractiveSession()
img1 = np.random.random([400, 600, 3])
img2 = np.random.random([400, 600, 3])
img3 = np.random.random([400, 600, 3])
images = [img1, img2, img3]
img1_crop = [100, 100, 100, 100]
img2_crop = [200, 150, 100, 100]
img3_crop = [150, 200, 100, 100]
crop_values = [img1_crop, img2_crop, img3_crop]
def crop_image(img, crop):
tf.image.crop_to_bounding_box(img,
crop[0],
crop[1],
crop[2],
crop[3])
image_placeholder = tf.placeholder("float", [None, 400, 600, 3])
crop_placeholder = tf.placeholder(dtype=tf.int32)
sess.run(tf.global_variables_initializer())
cropped_image = tf.map_fn(lambda img, crop: crop_image(img, crop), elems=[image_placeholder, crop_placeholder])
result = sess.run(cropped_image, feed_dict={image_placeholder: images, crop_placeholder:crop_values})
plt.imshow(result)
plt.show()
/Users/p111/anaconda/bin/python /Users/p111/PycharmProjects/analysis_code/testing.py
Traceback (most recent call last):
File "/Users/p111/PycharmProjects/analysis_code/testing.py", line 31, in
cropped_image = tf.map_fn(lambda img, crop: crop_image(img, crop), elems=[image_placeholder, crop_placeholder])
File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/functional_ops.py", line 390, in map_fn
swap_memory=swap_memory)
File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2636, in while_loop
result = context.BuildLoop(cond, body, loop_vars, shape_invariants)
File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2469, in BuildLoop
pred, body, original_loop_vars, loop_vars, shape_invariants)
File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/control_flow_ops.py", line 2419, in _BuildLoop
body_result = body(*packed_vars_for_body)
File "/Users/p111/anaconda/lib/python3.5/site-packages/tensorflow/python/ops/functional_ops.py", line 380, in compute
packed_fn_values = fn(packed_values)
TypeError: () missing 1 required positional argument: 'crop'
Edit: It appears that elems will only accept a single tensor. Which means I would need to somehow combine my two tensors into one, and then unpack it in my function to get the values out. I'm not sure how I would perform that kind of tensor manipulation. I have found the glimpse method already and that does work, however I am wondering if the same can be done with this specific method. Mostly, I'm wondering how you would combine and then split a pair of tensors so it can be used in this method.
I saw this code from here.
elems = (np.array([1, 2, 3]), np.array([-1, 1, -1]))
alternate = map_fn(lambda x: x[0] * x[1], elems, dtype=tf.int64)
# alternate == [-1, 2, -3]
It is possible to use a tuple or a list to pack several elements into one so I tried this.
import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np
sess = tf.InteractiveSession()
img1 = np.random.random([400, 600, 3])
img2 = np.random.random([400, 600, 3])
img3 = np.random.random([400, 600, 3])
images = np.array([img1, img2, img3])
# images = tf.convert_to_tensor(images) # it can be uncommented.
img1_crop = [100, 100, 100, 100]
img2_crop = [200, 150, 100, 100]
img3_crop = [150, 200, 100, 100]
crop_values = np.array([img1_crop, img2_crop, img3_crop])
# crop_values = tf.convert_to_tensor(crop_values) # it can be uncommented.
def crop_image(img, crop):
return tf.image.crop_to_bounding_box(img,
crop[0],
crop[1],
crop[2],
crop[3])
fn = lambda x: crop_image(x[0], x[1])
elems = (images, crop_values)
cropped_image = tf.map_fn(fn, elems=elems, dtype=tf.float64)
result = sess.run(cropped_image)
print result.shape
plt.imshow(result[0])
plt.show()
It works on my machine with tf version 0.11 and python2. Hope this can help you.
Couple of things :
You do not have a return statement in the crop_image function.
map_fn accepts a single argument.
I strongly advise you to separate the graph definition and the session usage.
--
# Graph def
def crop_image(img, crop):
return tf.image.crop_to_bounding_box(img,
crop[0],
crop[1],
crop[2],
crop[3])
image_placeholder = tf.placeholder(tf.float32, [None, 400, 600, 3])
crop_placeholder = tf.placeholder(dtype=tf.int32)
cropped_image = tf.map_fn(lambda inputs: crop_image(*inputs), elems=[image_placeholder, crop_placeholder], dtype=tf.float32)
# Session
sess = tf.InteractiveSession()
img1 = np.random.random([400, 600, 3])
img2 = np.random.random([400, 600, 3])
img3 = np.random.random([400, 600, 3])
images = [img1, img2, img3]
img1_crop = [100, 100, 100, 100]
img2_crop = [200, 150, 100, 100]
img3_crop = [150, 200, 100, 100]
crop_values = [img1_crop, img2_crop, img3_crop]
sess.run(tf.global_variables_initializer())
result = sess.run(cropped_image, feed_dict={image_placeholder: images, crop_placeholder:crop_values})
plt.imshow(result[0])
plt.show()
tf.map_fn(f, l) runs function f for every tensor in list l. In your case, your function expects 2 arguments, but since you supply a flat list, map_fn() sends them one by one. According to docs, map_fn() supports variable arity, so what you should do is something like this
tf.map_fn(lambda img, crop: crop_image(img, crop),
elems=([image_placeholder, crop_placeholder], ))
so the list you pass to map_fn contains pairs of arguments.

using cache in a complex structure

I'm using easeljs to build a certain structure.
Inside that structure, there are many containers and shapes.
I ran across a problem where I needed to change the color of a certain element when the user hovered it with his mouse. I managed to do it However there is a considerable delay until the color is drawn and return to its original color because the stage redraws itself.
I saw that I could use the cache for this purpose so I follow the example in the docs like this:
myShape.cache(150, 150, 100, 100, 1); however nothings happens and I don't see the shape.
I have to say that the shape resides inside a container which is added to the stage.
Here's the relevant code:
enter code here
var g = curShape.graphics.clone().clear();
g.beginFill("#2aa4eb");
g.drawRoundRect(0, 0, curShape.width, curShape.height, 1.5);
//g.drawRect(0, 0, curShape.width + 2, curShape.height + 2);
g.endFill();
g.endStroke();
var newShape= new createjs.Shape(g);
newShape.cache(150, 150, 100, 100, 2);
Any help would be appreciated
You are caching at x:150 and y:150, but you are drawing your shapes at 0,0. If your shape is smaller than 150x150, then it will be caching nothing. Change your cache to 0,0, and it should be fine.
Additionally, you are not providing the 5th parameter (corner radius) to the drawRoundRect call, which will make it fail. Here is a quick sample with a modified version of your code.
http://jsfiddle.net/LNXVg/
var stage = new createjs.Stage("canvas");
var g = new createjs.Graphics();
g.beginFill("#2aa4eb");
g.drawRoundRect(0, 0, 300, 200, 5);
var newShape = new createjs.Shape(g);
//newShape.cache(150, 150, 100, 100, 2);
newShape.cache(0, 0, 100, 100, 2);
stage.addChild(newShape);
stage.update();

Why can't I do an equality test of a synth parameter?

I'm mystified. In this code:
SynthDef(\acid,
{
|out, gate = 1, freq, myParam, amp, cutoff, resonance, filtEnvAmt|
var env, audio, filtEnv;
if (myParam == \something, { freq = 200; });
env = Linen.kr(gate, 0, 1, 0, doneAction: 2);
audio = LFSaw.ar(freq, mul: amp);
filtEnv = Line.kr(midicps(cutoff + filtEnvAmt), midicps(cutoff), 0.2);
audio = RLPFD.ar(audio, ffreq: filtEnv + MouseX.kr(0, 5000), res: MouseY.kr(0, 1), dist: 0);
Out.ar(out, audio * env);
}
).add;
b = Pbind(*[
out: 0,
instrument: \acid,
stepsPerOctave: 19,
scale: [0, 3, 5, 8, 11, 14, 17],
octave: 3,
degree: Pseq([0, \, 3, 3, 4, 4, 9, 4, 4]),
myParam: \something,
//prevFreq: Pseq([0, 0, 0, 0, 9, 0, 0, 0, 0]),
dur: Pseq([0.4, 0.4, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1]),
cutoff: Pseq([60, \, 50, 60, 80, 60, 90, 80, 50]),
filtEnvAmt: Pseq([20, \, 20, 20, 20, 20, -10, 20, 20]),
resonance: Pseq([0.5, \, 0.5, 0.5, 0.5, 0.5, 0.3, 0.5, 0.5])
]);
b.play;
..the equality test myParam == \something never returns true, despite the fact that the Pbind is clearly sending \something each time. No other value will work either: 0, nil etc.
The equality tests myParam == myParam and \something == \something do work however, so in these cases I get a monotone melody.
I can only guess that a Pbind sends each value in some kind of wrapper, but I've no idea how to then check them from inside the synth. Can anyone help?
First: you can't send symbols to a synth control. You can only send numbers.
Second: your example doesn't say what freq should be if the test is false. In fact, you should write it in more of a dataflow style such as:
freq = if(testcondition, 200, 300);
That's the kind of thing that will work in a synthdef.
Third is a slightly frustrating thing in sc language, which is that the == message is always evaluated at synthdef compile time - the equality is checked once, and then never again. In order to have "live" equality checking, you can use this slightly clunky expression:
BinaryOpUGen("==", thinga, thingb)
So in summary you might write
freq = if(BinaryOpUGen("==", myParam, 1), 200, 300);

unable to enter data in Input Control of a GUI in autoit

The below one is my code. I am unable to click and edit in the second Input control.
#include <GUIConstants.au3>
$gui = GuiCreate("Hello World", 700, 600)
$Label_HelloWorld = GuiCtrlCreateLabel("Path / Directory", 40, 20, 300, 18)
$file = GUICtrlCreateInput("", 140, 20, 300, 20)
$Label_boot = GuiCtrlCreateLabel("path of boot.c", 40, 60, 300, 18)
$file2 = GUICtrlCreateInput("", 140, 60, 300, 20)
$Button_OK = GuiCtrlCreateButton("CHECK", 400, 90, 50, 20)
GuiSetState(#SW_SHOW, $gui)
Sleep(10000)
Your labels are overlapping the controls (again), this time horizontally. A width of 300px when the inputs are 100px to the right means the first 200px is overlapping. If you try to click in the last 100px of the input then it will work.
This is very easy to check for, just use the autoit window info tool and look at the outlines of the controls.

Resources